首先,我们来了解一下Android内存管理。我们都知道Android应用框架是基于Java语言的,所以应用内存管理的工作也都由Java虚拟机来负责。Android系统使用的是不遵循JVM规范的Davlik虚拟机,与传统Java EE的JVM还是有些区别的,其特点归纳为一下几点:
a、Davlik虚拟机更接近Linux内核,支持多进程。
b、Davlik虚拟机基于寄存器,与传统基于栈的Java虚拟机不同。
c、Davlik虚拟机使用自己的字节码(.dex文件),不兼容传统的Java字节码格式。
d、Davlik虚拟机的常量池只使用32位的索引,以简化解释器。
e、Davlik虚拟机默认栈大小是12KB(3页、每页4KB)。
f、Davlik虚拟机默认堆启动大小是2MB,最大为16MB(该数值与设备有关,也有24MB、48MB的)。
其次,我们如何判断内存泄露。与Java语言环境类似,Android系统框架也为我们提供了HPROF工具来监控内存和CPU的使用情况。在Android开发环境中,我们主要使用Eclipse的MAT(Memory Analyzer)工具来获取准确的内存泄露报告。MAT工具可以在Eclipse的Help菜单中的Install New Software功能界面中安装,找到Eclipse更新站点下面的General Purpose Tools之下的Memory Analyzer选项,选中并安装即可。然后只要在DDMS界面的Devices选项栏中选中需要进行内存分析的进程,然后单击Dump HPROF File按钮就可生成当前的HPROF文件。
最后,我们介绍一些常见内存泄露的处理。我们需要知道Java中引起内存泄露的根本原因是引用了垃圾对象。简单来说就是程序引用了某些对象,但是却从来都没有使用过,致使GC无法正常回收,最终导致了内存溢出的问题。下面列出了一些常见问题的处理方式:
a、程序逻辑的内存泄露:一些不好的编程习惯可能在程序逻辑中造成内存泄露的隐患,比如在不恰当的位置销毁对象。
Vector customers = new Vector(100);
for (int =0;i<100;i++){
Customer customer = new Customer();
customers.add(customer);
customer = null;
}
b、数据库查询没有关闭游标:对于数据库游标这种大数据对象来说,使用过后必须关闭回收。
c、合理使用上下文对象(Context):最常见的Context上下文对象造成的内存泄露是因为超出本身的生命周期而导致的。如在一些生命周期比较长的对象中(Service)使用了某个Activity的Context对象,当这个Activity被销毁时,该Context对象就变成了垃圾对象。另外注意避免Activity内的控件对象声明为静态,这种做法在屏幕旋转的时候就可能产生内存泄露。
d、Bitmap对象不使用后未调用recycle方法释放内存,然后再将其设置为null。
e、构造Adapter时未使用缓存的View对象,主要是针对listview来说的。