Android内存泄漏监测(MAT)及解决办法

版权所有,禁止匿名转载;禁止商业使用。
BitmapFactory.Options options = new BitmapFactory.Options(); 
//只加载图片的部分信息,减少内存占用   
options.inJustDecodeBounds = true; 
Bitmap tmpBitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(new URL(url).openStream()), null, options); 
//获取图片的长宽像素   
int height = options.outHeight; 
int width = options.outWidth;

(2) 这样就在下载网络图片之前就可以知道图片的大小了,然后根据最终需要显示的图片大小进行压缩(通常Android会在绘制的时候缩放图片)


options = new BitmapFactory.Options(); 
options.inSampleSize = sampleSize;//压缩比列,如果是3,就会压缩到1/3 
bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(new URL(url).openStream()), null, options);

这样获取的图片内存占用会小一点。


(3) 更好的办法是将图片下载到本地,在使用的时候根据大小重新缩放。


将不再需要图片对象时调用bitmap.recyce()来释放掉图片的内存占用,但是如果你调用了

recycle(),之后又试图绘制这个bitmap,你会得到 错误:“Canvas: trying to use a recycled bitmap”(适合Android2.3及之前版本)。

7.ListView的convertView缓存方式 【网上资料很多】 


8.debug的时候会保持对象处于可用状态,内存不能被回收。所以内存分析(使用MAT工具)的时候不要使用debug。并且在heap dump之前多进行几次GC操作


【原因: http://groups.google.com/group/android-developers/browse_thread/thread/7b0ea57d9507d33f 】 


文章的回复里有个问题 


问题: 


我写了一个简单的demo,只有两个activity,重复打开SecondActivity 6次,使用MAT工具查看内存发现有6个SecondActivity对象,为什么会这样? 


回答: 


可能导致上述问题的原因 


(1) 怎么打开和关闭SecondActivity的,是通过Intent吗?是通过硬件返回按钮关闭SecondActivity的吗? 


(2) 在SecondActivity中重载onDestroy(),打上log,重复打开SecondActivity 6次,onDestroy()中的log会打印6次吗? 


(3) 用多快速度重新打开和关闭SecondActivity的?最好是当看见一个GC log时再重新打开,可能是还没有来得及GC,所以内存中会有多个对象(可有可能是你的demo内存占用太小,没有达到需要GC的条件) 


(4)检查一下6个SecondActivity对象的状态是否为unknown,MAT也会统计unkown状态的对象。【补充:可以使用adb shell dumpsys meminfo 命令查看当前内存中Activity存在的数目】 


0 0