1)OOM解析
首先你要明白Android系统会为每一个应用程序创建一个Dalvik虚拟机实例然后创建一个进程接着创建主线程,这样就组成了一个应用。那么创建一个虚拟机就会考虑到为每一个虚拟机分配内存DalvikHeap size,不同性能手机内存大小分配不同,早期有些机器分配16M也有些是24M,当然DalvikHeap size是一个区间有它最大阈值(可使用adb命令进行查看最大分配内存:adbshell getprop dalvik.vm.heapsize),当应用程序占用内存超过这个阈值就好引发OutOfMemoryError(俗称OOM)。出现OOM主要是应用内存申请越积越多,gc未来及回收从而超过Heapsize最大阈值。
主要有以下情况:
1、加载图片对象过大;
2、资源过多,来不及加载;
3、大量内存泄漏未释放。
常见避免OOM方案:
1、加载图片时如果图片过大适当调整图像大小做压缩处理;
2、图像采用低内存占用量的编码方式:Bitmap.Config.ARGB_4444;
3、加载网络图像采用2级缓存一般第三方都已经封装好了;
4、大量本地图片内存引用采用软引用;
5、Listview的Adapter重用缓存convertView传递给getView()避免重复inflate,使用ViewHolder模式来避免没有必要的调用findViewById从而减少内存消耗;
6、尽量避免内存泄漏(内存泄漏比较多放在下面在做详细介绍);
7、自定义堆内存分配大小,优化Dalvik虚拟机的堆内存分配;
2)内存泄漏解析
JAVA垃圾回收(garbagecollection,简称GC)去处理堆内存的回收,但如果对象一直被引用无法被回收,造成内存的浪费,无法再被使用,就造成了内存泄漏。
常见内存泄漏:
1、单例导致内存泄露主要是传入了Activity、Service的Context作为成员变量导致内存泄漏,可使用context.getApplicationContext()解决内存泄漏;
2、Activity的非静态内部了和匿名类,他们都持有Activity的引用容易导致内存泄漏,典型的Handler内部类持有Activity的引用,可以使用静态内部类软引用解除内部类对Activity的引用,从而解决内存泄漏;
3、Bitmap使用完未调用recycle(),导致内存泄漏,可在结束加上recycle()解决;
4、.数据库的cursor没有关闭,在结束关闭可解决;
5、调用register注册没有解绑,在结束后调用unregister解绑可解决;
6、Socket及IO没有关闭,在结束后关闭可解决;
7、Webview结束未销毁,在结束后销毁可解决。
mWebViewContainer.removeView(mWebView);
mWebView.stopLoading();
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.clearHistory();
mWebView.removeAllViews();
mWebView.destroy();