Dalvik虚拟机内存管理与垃圾回收相关

概述

这篇笔记摘抄自老罗的博客:
http://blog.csdn.net/luoshengyang/article/details/41338251
http://blog.csdn.net/luoshengyang/article/details/41822747
Dalvik虚拟机内存分配的底层依赖是基于Doug Lea编写的dlmalloc内存分配器的,在Heap上完成。按照分配规则,没进行一次内存分配都会经过数次尝试:
1. 第一次分配,如果失败,那么进行一次GC,这次GC不回收软引用对象。
2. 第二次分配,如果失败,就增长堆的大小,堆的大小是可以在堆的生长限制之内进行生长的。
3. 第三次分配,如果失败,再进行一次GC,这次GC会收集软引用对象。
4. 第四次分配,如果成功,则返回一个指向内存区域的指针,否则,如果失败,返回空指针并且抛出异常,虚拟机暂停工作。

而在Dalvik虚拟机中,用来分配对象的堆划分为两个部分,一部分叫做Active Heap,另一部分叫做Zygote Heap。


垃圾收集的过程

Dalvik中GC的一些数据结构:

三种情况
struct GcSpec {  
  /* If true, only the application heap is threatened. */  
  bool isPartial;  
  /* If true, the trace is run concurrently with the mutator. */  
  bool isConcurrent;  
  /* Toggles for the soft reference clearing policy. */  
  bool doPreserve;  
  /* A name for this garbage collection mode. */  
  const char *reason;  
};  
  1. isPartial:为true时表示仅回收Active堆的垃圾,为false时表示回收Active堆和Zygote堆的垃圾。
  2. isConcurrent:为true时表示执行并行GC,为false时表示执行非并行GC。
  3. doPreserve:为true时,表示在执行GC过程中,不回收软引用的对象,为false时表示回收软引用的对象。

4. reason:一个描述性的字符串。

四种类型GC
/* Not enough space for an "ordinary" Object to be allocated. */  
extern const GcSpec *GC_FOR_MALLOC;  

/* Automatic GC triggered by exceeding a heap occupancy threshold. */  
extern const GcSpec *GC_CONCURRENT;  

/* Explicit GC via Runtime.gc(), VMRuntime.gc(), or SIGUSR1. */  
extern const GcSpec *GC_EXPLICIT;  

/* Final attempt to reclaim memory before throwing an OOM. */  
extern const GcSpec *GC_BEFORE_OOM;  
  1. GC_FOR_MALLOC:表示是在堆上分配对象时内存不足触发的GC。
  2. GC_CONCURRENT:表示是在已分配内存达到一定量之后触发的GC。
  3. GC_EXPLICCT:表示是应用程序调用System.gc、VMRuntime.gc接口或者收到SIGUSR1信号时触发的GC。
  4. GC_BEFORE_OOM:表示是在准备抛OOM异常之前进行的最后努力而触发的GC。

怎样知道哪些对象需要被回收

在GC时,使用位图来存放对象的存活信息。如果一个对象被引用,那么它在Bitmap中与它对应的那一位就会被置为1,否则的话就是0。在Dalvik虚拟机中,使用一个unsigned long数组来描述一个Bitmap。
在GC时,DVM使用两个Bitmap来描述堆的对象,一个称为Live Bitmap,另一个称为Mark Bitmap。Live Bitmap用来标记上一次GC时被引用的对象,也就是没有被回收的对象。而Mark Bitmap用来标记当前GC有被引用的对象。有了这两个信息之后,我们就可以很容易的知道哪些对象是需要被回收的,即在Live Bitmap中标记为1,但是在Mark Bitmap中标记为0的对象。

这里有个要注意的,一开始没想明白为什么要对比Live Bitmap和Mark Bitmap,为什么不能直接扫描Mark Bitmap,为0的就是要回收的。想了一会才想通,在Mark Bitmap中会对存活的对象置1,而未分配的内存与应回收的内存,都是0,而未分配的内存是不需要进行回收的。因此可以通过对比Live Bitmap和Mark Bitmap获取到需要回收的对象是哪些。


CMS(Concurrent Mark Sweep)收集器

CMS是一种以获取最短回收停顿时间为目标的收集器。整个过程分为4个步骤,包括:
1. 初始标记(CMS initial mark)
2. 并发标记(CMS concurrent mark)
3. 重新标记(CMS remark)
4. 并发清除(CMS concurrent sweep)

你可能感兴趣的:(android)