说说内存泄露那点事
2015-04-10 11:32
351 查看
说说内存泄露那点事
2013-05-09 19:21 by HalZhang, 840 阅读, 2 评论, 收藏, 编辑先看看一个例子:
1 private static Drawable sBackground; 2 3 @Override 4 protectedvoid onCreate(Bundle state){ 5 super.onCreate(state); 6 7 TextView label =newTextView(this); 8 label.setText("Leaks are bad"); 9 10 if(sBackground ==null){ 11 sBackground = getDrawable(R.drawable.large_bitmap); 12 } 13 label.setBackgroundDrawable(sBackground); 14 15 setContentView(label); 16 } 17
上面几行代码,内存泄露挺严重的。sBackground是一个 static 变量,在 label调用setBackgroundDrawable的时候,会调用sBackground的setCallback,所以在sBackground中就存在label的引用。
而,label中又存在Activity的引用,所以此Activity一直不会被回收,即使已经finish了。
如何避免:
使用applicationContext作为上下文,避免使用activity
设置Drawable的Callback为null
在Service或者Activity使用内部类尽量使用static类。例如:使用Handler
关于第3点,看个例子:
1 static class IncomingHandlerextendsHandler { 2 private final WeakReference<UDPListenerActivity> mActivity; 3 4 IncomingHandler(UDPListenerActivity activity) { 5 mService = newWeakReference < UDPListenerActivity > (activity); 6 } 7 8 @Override 9 public void handleMessage(Message msg) { 10 UDPListenerActivity activity = mActivity.get(); 11 if (activity != null) { 12 activity.handleMessage(msg); 13 } 14 } 15 }
我们知道,Message发出之后是存在MessageQueue中的,有些Message也不是马上就被处理的。在Message存在一个 target,是Handler的一个引用,如果Message在Queue中存在的时间越长,就会导致Handler无法被回收。如果Handler是非静态的,则会导致Activity或者Service不会被回收。
所以正确处理Handler等之类的内部类,应该采用上述代码。
参考:
http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler
http://android-developers.blogspot.jp/2009/01/avoiding-memory-leaks.html
-----END-----
相关文章推荐
- 说说内存泄露那点事
- 关于android内存泄露那点事
- java程序会发生内存泄露的问题吗?请简单说说你的观点
- java程序会发生内存泄露的问题吗?请简单说说你的观点
- 说说JS在IE中的内存泄露问题
- 内存泄露
- Android必知必会-Handler可能引起的内存泄露
- Java内存泄露的理解与解决
- 堆转储快照分析内存泄露
- android handler的内存泄露问题
- TCMalloc的使用与源码剖析之八---------TCMalloc内存分配与释放的管理之内存泄露检查
- VC 检测内存泄露的几种方法
- Android 性能优化之使用MAT分析内存泄露问题
- android native 代码内存泄露 定位方案
- Django 内存泄露问题
- 内存泄露(一)
- CComBSTR 内存泄露的问题
- JAVA垃圾回收机制与内存泄露问题
- Android内存泄露原因
- iPhone开发 - 内存泄露(不断更新)