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存在的数目】