浅谈Android系统的基本体系结构与内存管理优化

2019-12-10 19:07:50王冬梅

内存泄露(Memory Leak)
Java内存泄漏指的是进程中某些对象(垃圾对象)已经没有使用价值了,但是它们却可以直接或间接地引用到gc roots导致无法被GC回收。Dalvik VM具备的GC机制(垃圾回收机制)会在内存占用过多时自动回收,严重时会造成内存溢出OOM。

内存溢出OOM
当应用程序申请的java heap空间超过Dalvik VM HeapGrowthLimit时,溢出。
注意:OOM并不代表内存不足,只要申请的heap超过Dalvik VM HeapGrowthLimit时,即使内存充足也会溢出。效果是能让较多进程常驻内存。

如果RAM不足时系统会做什么?
Android的Memory Killer会杀死优先级较低的进程,让高优先级进程获取更多内存。

Android系统默认内存回收机制

进程优先级:Foreground进程、Visible进程、Service进程、Background进程、Empty进程;
如果用户按Home键返回桌面,那么该app成为Background进程;如果按Back返回,则成为Empty进程
ActivityManagerService直接管理所有进程的内存资源分配。所有进程要申请或释放内存都需要通过ActivityManagerService对象。
垃圾回收不定期执行。当内存不够时就会遍历heap空间,把垃圾对象删除。
堆内存越大,则GC的时间更长

浅谈Android系统的基本体系结构与内存管理优化

二、优化
Bitmap优化
Bitmap非常消耗内存,而且在Android中,读取bitmap时, 一般分配给虚拟机的图片堆栈只有8M,所以经常造成OOM问题。所以有必要针对Bitmap的使用作出优化:

  • 图片显示:加载合适尺寸的图片,比如显示缩略图的地方不要加载大图。
  • 图片回收:使用完bitmap,及时使用Bitmap.recycle()回收。
  • 问题:Android不是自身具备垃圾回收机制吗?此处为何要手动回收。
  • Bitmap对象不是new生成的,而是通过BitmapFactory生产的。而且通过源码可发现是通过调用JNI生成Bitmap对象(nativeDecodeStream()等方法)。所以,加载bitmap到内存里包括两部分,Dalvik内存和Linux kernel内存。前者会被虚拟机自动回收。而后者必须通过recycle()方法,内部调用nativeRecycle()让linux kernel回收。