先讲一下内存泄露、内存溢出与内存抖动的含义
内存泄露就是一个对象已经使用完,可以被回收,但由于其他原因导致没有被GC导致内存泄露,危害?内存泄漏对于app没有直接的危害,即使app有发生内存泄漏的情况,也不一定会引起app崩溃,但是会增加app内存的占用。内存得不到释放,慢慢的会造成app内存溢出。解决内存泄漏目的就是防止app发生内存溢出。
内存溢出(out of memory)是指程序new一个对象,程序向系统申请的空间操作了系统能够给的大小,内存泄露很容易产生内存溢出
内存抖动指程序在某个时刻不停的在进行申请内存空间或者回收内存空间,比如循环中不停的在new对象或者GC,这种情况是应该避免的
内存泄露原因在于长生命周期对象持有短生命周期对象,短生命周期对象由于处于无用状态可以被GC,但由于长生命周期对象任然持有短生命周期对象的引用导致无法被垃圾收集器回收。
- BraodcastReceiver,ContentObserver,输出流输入流,游标 Cursor,Bitmap,activity结束之后动画,使用完必须关闭或者清空
- Adapter中没有使用缓存的convertView
- 成员方法中使用完对象未及时释放 example:mHandler.post(run()) run里面使用完成员变量应该可以被释放,但包含成员变量的对象还未释放
- Bitmap使用完之后一般recycle掉 然后赋值null
- 静态集合类 HashMap、Vector
- 当集合里面的对象属性被修改后,再调用remove()方法时不起作用
- 监听器有注册必须有注销
- 单例对象持有外部的引用
- 对 Activity 等组件的引用应该控制在 Activity 的生命周期之内; 如果不能就考虑使用 getApplicationContext 或者 getApplication,以避免 Activity 被外部长生命周期的对象引用而泄露
- 匿名内部类/非静态内部类/异步线程/Handler example: 非静态内部类
public class MainActivity extends AppCompatActivity {
private static TestResource mResource = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(mManager == null){
mManager = new TestResource();
}
//...
}
class TestResource {
//...
}
}
内存泄露的检测方法
- MAT工具 http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.mat.ui.help%2Fgettingstarted%2Fbasictutorial.html&cp=49_1_0
- LeakCanary
LeakCanary比较简单这里就不讲了,主要讲一下MAT的使用,讲几个概念
Shallow heap & retained heap 如下图所示:
其中shallow heap指当前对象的大小不包括引用的对象的大小;retained heap指当前对象大小和它直接引用或间接引用的对象大小之和。
关于hprof文件抓取方式