查看内存的使用情况:
1.adb命令:
adb shell dumpsys meminfo
使用dumpsys 可以查看具体的进程的内存使用。
adb shell dumpsys meminfo $package_name or $pid
2.DDMS的heap:
在这里很容易的看出进程的内存使用情况。当你进行操作的时候,在图片右边的部分 会自动的刷新内存改变。
3.使用第三方插件,比如MAT之类的。
4.使用android API ,查看内存使用情况。使用起来比前面的复杂,而且也不直观。
常见的造成内存使用过高问题的原因:
1.Cursor忘记关闭:
数据库操作,如长时间进行大量数据查询等操作的时候,都会消耗大量内存。所以,在使用了游标后,要记得关闭。
2.Adapter的优化:
在google io大会上,早就给出适配器中使用ViewHolder作为降低内存使用的最优方案。这就不多说了。
3.Bitmap没有回收。
在程序中,对图片的操作是需要谨慎的,单张的图片也许没啥,图片多了就会让人头疼了。对流,byte[]和bitmap这类容易跟大量数据交互的类,要小心使用。在使用过后,要注意释放。
除了及时回收bitmap对象,在使用bitmap对象的时候,一般还使用BitmapFactory类对bitmap进行 压缩:
BitmapFactory.Options ops = null;
Bitmap bm;
ops = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(viewHolder.imagePath, ops);
// 不需要透明度,节约一半内存
ops.inPreferredConfig = Config.ARGB_8888;
// 让系统能及时回收内存
ops.inPurgeable = true;
ops.inInputShareable = true;
// 压缩图片
ops.inJustDecodeBounds = true;
ops.inSampleSize = getSampleSize(ops);
ops.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(viewHolder.imagePath, ops);
得到压缩的比例。
public int getSampleSize(BitmapFactory.Options options) {
int inSample = 1;
float nowWd = options.outWidth;
float nowHg = options.outHeight;
float reqWd = 60;
float reqHg = 60;
// 计算压缩比
if (nowWd > nowHg && nowWd > reqHg) {
inSample = (int) Math.ceil(nowWd / reqWd);
} else if (nowHg > nowWd && nowHg > reqHg) {
inSample = (int) Math.ceil(nowHg / reqHg);
}
return inSample;
}
4.及时释放引用:
如 object =null;System.gc();
当然,采用弱,软和虚引用,都能对内存的优化起到很大的作用。
5.尽量少用静态的成员或者对象。
静态的生命周期一般都比较长,即使不使用了也会长期的占用内存,而且提高了耦合度。不是必要的话,尽量少用吧。
6.多线程的内存泄漏问题。线程周期不可控及run()不结束,线程不会销毁,从而造成内存泄漏。
一般解决的办法:将线程的内部类改为静态的内部类 ,将线程的内部采用弱引用的context。