(VR虚拟现实)D虚拟机垃圾收集(GC)过程分析

上传人:下**** 文档编号:137344489 上传时间:2020-07-07 格式:DOC 页数:54 大小:552.11KB
返回 下载 相关 举报
(VR虚拟现实)D虚拟机垃圾收集(GC)过程分析_第1页
第1页 / 共54页
(VR虚拟现实)D虚拟机垃圾收集(GC)过程分析_第2页
第2页 / 共54页
(VR虚拟现实)D虚拟机垃圾收集(GC)过程分析_第3页
第3页 / 共54页
亲,该文档总共54页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《(VR虚拟现实)D虚拟机垃圾收集(GC)过程分析》由会员分享,可在线阅读,更多相关《(VR虚拟现实)D虚拟机垃圾收集(GC)过程分析(54页珍藏版)》请在金锄头文库上搜索。

1、(VR虚拟现实)D虚拟机垃圾收集(GC)过程分析Dalvik虚拟机垃圾收集(GC)过程分析前面我们分析了Dalvik虚拟机堆的创建过程,以及Java对象在堆上的分配过程。这些知识都是理解Dalvik虚拟机垃圾收集过程的基础。垃圾收集是一个复杂的过程,它要将那些不再被引用的对象进行回收。一方面要求Dalvik虚拟机能够标记出哪些对象是不再被引用的。另一方面要求Dalvik虚拟机尽快地回收内存,避免应用程序长时间停顿。本文就将详细分析Dalvik虚拟机是如何解决上述问题完成垃圾收集过程的。Dalvik虚拟机使用Mark-Sweep算法来进行垃圾收集。顾名思义,Mark-Sweep算法就是为Mark

2、和Sweep两个阶段进行垃圾回收。其中,Mark阶段从根集(Root Set)开始,递归地标记出当前所有被引用的对象,而Sweep阶段负责回收那些没有被引用的对象。在分析Dalvik虚拟机使用的Mark-Sweep算法之前,我们先来了解一下什么情况下会触发GC。 Dalvik虚拟机在三种情况下会触发四种类型的GC。每一种类型GC使用一个GcSpec结构体来描述,它的定义如下所示:cpp view plain copy 在CODE上查看代码片派生到我的代码片struct GcSpec /* If true, only the application heap is threatened. */

3、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; ; 这个结构体定义在文件dalvik/vm/alloc/Heap.h中。 GcSpec结构体的各个成员变量的含义如下所示: is

4、Partial: 为true时,表示仅仅回收Active堆的垃圾;为false时,表示同时回收Active堆和Zygote堆的垃圾。 isConcurrent: 为true时,表示执行并行GC;为false时,表示执行非并行GC。 doPreserve: 为true时,表示在执行GC的过程中,不回收软引用引用的对象;为false时,表示在执行GC的过程中,回收软引用引用的对象。 reason: 一个描述性的字符串。 Davlik虚拟机定义了四种类的GC,如下所示:cpp view plain copy 在CODE上查看代码片派生到我的代码片/* Not enough space for an

5、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 recl

6、aim memory before throwing an OOM. */ extern const GcSpec *GC_BEFORE_OOM; 这四个全局变量声明在文件dalvik/vm/alloc/Heap.h中。 它们的含义如下所示: GC_FOR_MALLOC: 表示是在堆上分配对象时内存不足触发的GC。 GC_CONCURRENT: 表示是在已分配内存达到一定量之后触发的GC。 GC_EXPLICIT: 表示是应用程序调用System.gc、VMRuntime.gc接口或者收到SIGUSR1信号时触发的GC。 GC_BEFORE_OOM: 表示是在准备抛OOM异常之前进行的最后努力

7、而触发的GC。 实际上,GC_FOR_MALLOC、GC_CONCURRENT和GC_BEFORE_OOM三种类型的GC都是在分配对象的过程触发的。 在前面一文,我们提到,Dalvik虚拟机在Java堆上分配对象的时候,在碰到分配失败的情况,会尝试调用函数gcForMalloc进行垃圾回收。 函数gcForMalloc的实现如下所示:cpp view plain copy 在CODE上查看代码片派生到我的代码片static void gcForMalloc(bool clearSoftReferences) . const GcSpec *spec = clearSoftReferences

8、? GC_BEFORE_OOM : GC_FOR_MALLOC; dvmCollectGarbageInternal(spec); 这个函数定义在文件dalvik/vm/alloc/Heap.cpp中。 参数clearSOftRefereces表示是否要对软引用引用的对象进行回收。如果要对软引用引用的对象进行回收,那么就表明当前内存是非常紧张的了,因此,这时候执行的就是GC_BEFORE_OOM类型的GC。否则的话,执行的就是GC_FOR_MALLOC类型的GC。它们都是通过调用函数dvmCollectGarbageInternal来执行的。 在前面一文,我们也提到,当Dalvik虚拟机成功地

9、在堆上分配一个对象之后,会检查一下当前分配的内存是否超出一个阀值,如下所示:cpp view plain copy 在CODE上查看代码片派生到我的代码片void* dvmHeapSourceAlloc(size_t n) . HeapSource *hs = gHs; Heap* heap = hs2heap(hs); if (heap-bytesAllocated + n hs-softLimit) . return NULL; void* ptr; if (gDvm.lowMemoryMode) . ptr = mspace_malloc(heap-msp, n); . else ptr

10、 = mspace_calloc(heap-msp, 1, n); . countAllocation(heap, ptr); . if (heap-bytesAllocated heap-concurrentStartBytes) . dvmSignalCond(&gHs-gcThreadCond); return ptr; 这个函数定义在文件dalvik/vm/alloc/HeapSource.cpp中。 函数dvmHeapSourceAlloc成功地在Active堆上分配到一个对象之后,就会检查Active堆当前已经分配的内存(heap-bytesAllocated)是否大于预设的阀值(

11、heap-concurrentStartBytes)。如果大于,那么就会通过条件变量gHs-gcThreadCond唤醒GC线程进行垃圾回收。预设的阀值(heap-concurrentStartBytes)是一个比指定的堆最小空闲内存小128K的数值。也就是说,当堆的空闲内不足时,就会触发GC_CONCURRENT类型的GC。 GC线程是Dalvik虚拟机启动的过程中创建的,它的执行体函数是gcDaemonThread,实现如下所示:cpp view plain copy 在CODE上查看代码片派生到我的代码片static void *gcDaemonThread(void* arg) dvm

12、ChangeStatus(NULL, THREAD_VMWAIT); dvmLockMutex(&gHs-gcThreadMutex); while (gHs-gcThreadShutdown != true) bool trim = false; if (gHs-gcThreadTrimNeeded) int result = dvmRelativeCondWait(&gHs-gcThreadCond, &gHs-gcThreadMutex, HEAP_TRIM_IDLE_TIME_MS, 0); if (result = ETIMEDOUT) /* Timed out waiting for a GC request, schedule a heap trim. */ trim = true; else dvmWaitCond(&gHs-gcThreadCond, &gHs-gcThreadMutex); . dvmLockHeap(); if (!gDvm.gcHeap-gcRunning) dvmChangeStatus(NULL, THREAD_RUNNING); if (trim) trimHeaps(); gHs-gcThreadTrimNeeded = false; else dvmCollectGarbageInternal(GC_CONCURRENT); gH

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业/管理/HR > 商业计划书

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号