须要留意的是:应用静态内部类 + WeakReference 这种方法,每次应用前留意判空。
前面提到了 WeakReference,所以这里就R单的说一下 Java 对象的几种引用类型。
Java对引用的分类有 Strong reference, SoftReference, WeakReference, PhatomReference 四种。
ok,持续回到主题。前面所说的,创建一个静态Handler内部类,然后对 Handler 持有的对象应用弱引用,如许在收受接收时也可以收受接收 Handler 持有的对象,然则如许做固然避免了Activity泄漏,不过Looper 线程的消息队列中照样可能会有待处理的消息,所以我们在Activity的 Destroy 时或者 Stop 时应当移除消息队列 MessageQueue 中的消息。
下面几个办法都可以移除 Message:
- public final void removeCallbacks(Runnable r);
- public final void removeCallbacks(Runnable r, Object token);
- public final void removeCallbacksAndMessages(Object token);
- public final void removeMessages(int what);
- public final void removeMessages(int what, Object object);
尽量避免应用 staic 成员变量
如不雅成员变量被声明为 static,那我们都知道其生命周期将与全部app过程生命周期一样。
这里修复的办法是:
不要在类初始时初始化静态成员。可以推敲lazy初始化。
- public class TestActivity extends AppCompatActivity {
- //....
- private Runnable runnable=new Runnable() {
- @Override
- public void run() {
- }
- };
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //......
- }
- }
架构设计上要思虑是否真的有须要如许做,尽量避免。如不雅架构须要这么设计,那么此对象的生命周期你有义务治理起来。
- 避免 override finalize():
- finalize 办法被履行的时光不肯定,不克不及依附与它来释放紧缺的资本。时光不肯定的原因是: 虚拟机调用GC的时光不肯定以及Finalize daemon线程被调剂到的时光不肯定。
- finalize 办法只会被履行一次,即使对象被复生,如不雅已经履行过了 finalize 办法,再次被 GC 时也不会再履行了,原因是:含有 finalize 办法的 object 是在 new 的时刻由虚拟机生成了一个 finalize reference 在来引用到该Object的,而在 finalize 办法履行的时刻,该 object 所对应的 finalize Reference 会被释放掉落,即使在这个时刻把该 object 复生(即竽暌姑强引用引用住该 object ),再第二次被 GC 的时刻因为没有了 finalize reference 与之对应,所以 finalize 办法不会再履行。
- 含有Finalize办法的object须要至少经由两轮GC才有可能被释放。
其它
内存泄漏检测对象强烈推荐 squareup 的 LeakCannary,但须要留意Android版本是4.4+的,不然会Crash。
如上局部变量s2和mSample2存放在栈内存中,mSample3所指向的对象存放在堆内存中,包含该对象的成员变量s1和mSample1也存放在堆中,而它本身则存放在栈中。
推荐阅读
此次的成功融资让金山云的用户也跟着受益,因为金山云的主流产品将周全降价,个中CDN、云数据库Redis新价动人,降幅最大年夜可达到50%、60%;云办事器价格最大年夜降幅跨越30%;对象存储产品>>>详细阅读
本文标题:Android面试被问到内存泄漏了杂整?
地址:http://www.17bianji.com/lsqh/39898.html
1/2 1