Android会自动管理内存,JAVA也有garbage collection (GC )内存回收机制。
但是如果程序在一次操作中打开几个M的文件,那么通常会出现下面的错误信息。
1.明确调用System.gc();
这种内存回收会有一定的作用,但是请不要太期待。
System.gc()在调用时程序是处于阻塞状态,系统考虑到程序运行的流畅性,会分批次进行垃圾回收,每次只回收一部分,我曾经遇到过的状况是只调用了一次System.gc(),然后看到LOG显示垃圾的确回收了,但很快Out of memory便接踵而至,看来是垃圾还没有回收完,系统内存就溢出了,最后采用了一个无奈的方法,连续调用10次甚至20次System.gc(),问题便解决了。
2.图片处理完成后回收内存。
请在调用BitMap进行图片处理后进行内存回收。
bitmap.recycle();
这样会把刚刚用过的图片占用的内存释放。
3.图片读入内存时指定大小。
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
bitmap = BitmapFactory.decodeFile(path, options); // 此时返回bm为空
options.inJustDecodeBounds = false;
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = (int) (options.outHeight / (float) heigh);
if (be <= 0)
be = 1;
options.inSampleSize = be;
// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(path, options);
4.Drawable和Bitmap的区别
对比项 | Bitmap | Drawable |
显示清晰度 | 相同 | 相同 |
占用内存 | 大 | 小 |
支持缩放 | 是 | 是 |
支持色相色差调整 | 是 | 否 |
支持旋转 | 是 | 是 |
支持透明色 | 是 | 是 |
绘制速度 | 慢 | 快 |
支持像素操作 | 是 | 否 |
Drawable在内存占用和绘制速度这两个非常关键的点上胜过Bitmap
5.问题排查
从以下几点进行分析和排查:
1 | 所有不再使用的类对象你置空了吗? |
2 | 被置空的那些对象里的那些申请了内存空间的子对象(比如Bitmap对象)你释放资源以及置空了吗? |
3 | 置空对象后有没有调用System.gc()? |
6.Android框架,每一个进程都有内存限制,可以采用以下方法来躲开这个问题
每一个程序可以通过android.os.Debug.getNativeHeapAllocatedSize()查看进程可以使用的内存。
一种方法是从本机代码分配内存。使用NDK的(本地开发工具包)和JNI,它可以从C级(如的malloc / free或新/删除),这种分配的内存分配,不计入内存的限制。
另一种方法,效果很好,图像,是使用OpenGL纹理 - 纹理内存同样不被计入内存的限制
据说可以达到300M的内存使用,哪位朋友测试了可以告诉我,这个方法的可行性。
7.软引用
8.有MAT测试