Android面试宝典3.0,内容:JavaSE 基础,JavaSE 高级,Android 基础,Android 高级,Android 项目,项目面试常见问题,面试实战记录,BAT 面试题,Android 最新技术。
每次看阳哥的面试宝典都收货颇多。无论是代码质量还是语言修辞的衔接,恐怕即便是站在巨人的肩膀上,要追上技术牛人的脚步也要付出常人难以接受的努力吧。
对于这篇面试总结,简直喜欢和崇拜的不行。
说了太多的废话,占了几段篇幅,还是直接切入重点吧。
对于性能分析,也经常搜索相关资料,恕我才疏学浅,但还是忍不住发表一下观点。
先来看看Square公司给出的在Android中内存泄露的解释:
> What is a memory leak?
Some objects have a limited lifetime. When their job is done, they are expected to be garbage collected. If a chain of references holds an object in memory after the end of its expected lifetime, this creates a memory leak. When these leaks accumulate, the app runs out of memory.
>
For instance, after Activity.onDestroy() is called, the activity, its view hierarchy and their associated bitmaps should all be garbage collectable. If a thread running in the background holds a reference to the activity, then the corresponding memory cannot be reclaimed. This eventually leads to an OutOfMemoryError crash.
有些对象有一个有限的生命周期,当他们任务结束的时候,应该被GC回收。如果在该对象生命周期结束的时候,仍然有一系列对象hold住了该对象的引用,就会导致内存泄露。随着泄露的积累,app将内存将消耗殆尽。、
比如Activity.onDestroy( )被回调之后,view层级树以及关联的bitmap都应该被GC回收,如果一个正在运行的后台线程hold住了这个activity的引用,与其相关的内存将不会被回收,最终会导致outOfMemoryError崩溃。
从而可见,OOM一般代表着更深层次的问题:Memory Leak
由此可见,内存泄露指的是程序中一些对象不会被GC回收,而始终占用内存,即在对象的引用链中变成了可达不可用。而内存溢出是指程序运行期间无法申请足够的内存而导致的错误,可以说内存泄露是内存溢出的一种诱因,但是不唯一因素。
那么看一下这个著名的诞生于2009年的static Drawable例子,然后在SDK中查看一下历代SDK版本号,会发现
/**
* December 2009: Android 2.0.1
*/
public static final int ECLAIR_0_1 = 6;
/**
* January 2010: Android 2.1
*/
public static final int ECLAIR_MR1 = 7;
2009年的最后一个版本是2.0.1。2.1版本才出现在2010年,而且这个年代,貌似国内做Android的人少之甚少。
所以只需要把这些SDK的版本,翻看一遍,确实会发现这个有内存泄露隐患的强引用链:
Drawable->TextView->Context
但是如果看一下划时代的3.0版本(HONEYCOMB),会发现Google的Android小组貌似已经注意到了这个问题,并且修复了它。
由
public final void setCallback(Callback cb) {
mCallback = cb;
}
替换为
public final void setCallback(Callback cb) {
mCallback = new WeakReference<Callback>(cb);
}
用弱引用来代替强引用,这样就避免了Context的泄露。
再来说说Bitmap.recycle()。
这个也可以算是一个历史遗留问题。在3.0版本之前。
Bitmap.java源码。
// Note: mNativeBitmap is used by FaceDetector_jni.cpp
// Don't change/rename without updating FaceDetector_jni.cpp
private final int mNativeBitmap;
Bitmap的资源是在底层C中处理的,因此3.0之前的.recycle(),并没有什么错。但是在3.0以及之后。
Bitmap.java源码。
/**
* Backing buffer for the Bitmap.
*/
private byte[] mBuffer;
图片数据保存在成员变量mBuffer中,也就是说使用Heap存储代替了底层C处理。因此不用显式调用.recycle()。只需要把bitmap置null或者使用虚引用持有就行了。这样图片就能被GC回收了。
另外,由于不同版本的SDK,.recycle()注释也不同,但是有一句话是始终没有改变的
>This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.
这是一个高级函数,一般情况下没必要调用,在没有引用指向bitmap时,GC会自动释放内存。
而且我的建议是不要频繁的调用System.gc();因为这在大多情况下只能显式提醒GC回收,究竟什么时候进行回收操作,还是看VM自身的算法和调度。
76.4M / 03-25
立即下载55M / 06-05
立即下载237.9M / 04-13
立即下载140.5M / 03-06
立即下载900.9M / 03-02
立即下载96.2M / 07-06
立即下载311.2M / 07-06
立即下载335M / 07-06
立即下载200M / 07-06
立即下载413.8M / 07-06
立即下载353.9M / 06-05
立即下载131.8M / 04-13
立即下载230.8M / 03-03
立即下载195.6M / 03-03
立即下载165.4M / 03-03
立即下载45.6M / 09-08
立即下载665.2M / 07-06
立即下载2.84G / 07-06
立即下载93M / 07-06
立即下载338.3M / 07-06
立即下载1.38G / 07-26
立即下载488.3M / 07-16
立即下载109.8M / 06-03
立即下载142M / 01-08
立即下载1.2M / 11-23
立即下载548.8M / 04-13
立即下载1.6M / 04-13
立即下载1.48G / 03-18
立即下载646.6M / 03-03
立即下载133.7M / 03-03
立即下载325.8M / 06-07
立即下载60M / 04-29
立即下载254M / 04-25
立即下载659M / 04-23
立即下载1M / 12-26
立即下载253.4M / 12-08
立即下载253M / 12-08
立即下载1.19G / 11-16
立即下载110.5M / 04-23
立即下载26.7M / 03-16
立即下载488.3M / 07-16
立即下载248.9M / 12-08
立即下载248.9M / 12-08
立即下载201.2M / 04-13
立即下载100.6M / 03-06
立即下载148.9M / 03-06
立即下载1.12G / 07-06
立即下载1.25G / 07-06
立即下载9.48G / 07-06
立即下载50KB / 07-06
立即下载116.2M / 04-10
立即下载1.92G / 04-17
立即下载201.5M / 04-13
立即下载7.31G / 07-01
立即下载94.3M / 07-06
立即下载2.48G / 07-06
立即下载7.63G / 07-06
立即下载1M / 07-06
立即下载778.1M / 07-06
立即下载509.7M / 07-06
立即下载561.8M / 07-11
立即下载1.32G / 01-19
立即下载72M / 07-06
立即下载548.7M / 07-06
立即下载1.00G / 07-06
立即下载9.13G / 07-06
立即下载126.2M / 07-06
立即下载72M / 07-06
立即下载105.1M / 07-06
立即下载132M / 07-06
立即下载