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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章