android常见内存泄漏原因和解决办法:
内存泄漏:生命周期不匹配,长生命周期的对象持有短生命周期对象的引用,导致短生命周期对象无法及时回收
1.单例造成泄漏getInstance(Context context)
原因:单例对象一般是和应用的生命周期一样长,假如Context用activity实例化单例,会导致activity无法回收。
解决:应使用context.getApplicationContext()。
2.非静态内部类创建静态实例造成泄漏
原因:Java中非静态内部类持有外部类的引用,用非静态内部类创建的实例生命周期和应用一样长,导致外部类实例无法回收。
解决:内部类定义写成静态类。
3.handler造成泄漏
原因:message耗时任务没有处理完,message持有handler引用,handler持有activity引用,导致activity泄漏
解决:a.将handler声明为静态内部类;b.通过弱引用的方式引入activity
4.线程造成泄漏
原因:创建子线程asynctask和Thread/Runnable非静态内部类持有外部类引用,而子线程中耗时任务没完成activity关闭无法回收。
解决:创建子线程asynctask和Thread/Runnable定义成静态内部类
5.webview造成泄漏
webview打开网页会申请大量的堆内存,用于缓存网页和图片,所有webview内存泄漏应该引起重视。
原因:webview内部开起了很多线程,可能会泄漏。
解决:a.webview所在activity单独写在一个进程中,在退出activity杀死进程。
protected void onDestroy() {
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());
}
b.不能在布局文件中写Webview,动态创建webview
@Override protected void onDestroy() { super.onDestroy(); if (mWebView != null) { RelativeLayout parent = (RelativeLayout) mWebView.getParent(); parent.removeAllViews(); mWebView.removeAllViews(); mWebView.destroy(); mWebView = null; } }
强引用>软引用>弱引用>虚引用
强引用:宁愿oom也不会被回收
软引用:Gc扫描到内存不够时才回收,softReference和referenceQueue联合使用
弱引用:GC扫描到直接回收,不管内存够不够。WeakReference和referenceQueue联合使用
虚引用:GC在任何时候都可以回收掉,形同虚设。
referenceQueue:软引用或弱引用的对象被回收时,Java虚拟机就会把这个引用加入到与之关联的引用队列中。