理论教育 与垃圾收集算法相关的函数

与垃圾收集算法相关的函数

时间:2023-06-19 理论教育 版权反馈
【摘要】:在源文件alloc/MarkSweep.h中,定义了和垃圾收集有关的函数,各个函数的具体说明如下。函数markStackPush的功能是在堆栈中做一个标记,具体实现代码如下。函数nextGrayObject的功能是向前扫描标记对象,如果没有标记对象,在这一区域返回NULL。在垃圾收集时,需要对与老一代中卡片相关联的标记位进行检查,对脏的卡片扫描以寻找对年轻代有引用的对象。根据上一个函数给出的根对象位图,调用函数dvmHeapScanMarkedObjects对每一个与根相关的位图进行计算,如果这个根对象有被引用,就标记为使用。

与垃圾收集算法相关的函数

在源文件alloc/MarkSweep.h中,定义了和垃圾收集有关的函数,各个函数的具体说明如下。

(1)函数createMarkStack的功能是,创建初始化堆栈顶部和建议需要的标记堆栈页。具体实现代码如下。

(2)函数destroyMarkStack的功能是,销毁无效的栈顶和建议不需要的标记堆栈页。具体实现代码如下。

(3)函数markStackPush的功能是在堆栈中做一个标记,具体实现代码如下。

(4)函数markStackPop的功能是在标记栈中加入一个对象,具体实现代码如下。

(5)调用函数dvmHeapBeginMarkStep()创建位图,并从对象位图里复制一份位图出来,以便后面对这个位图进行标记。函数dvmHeapBeginMarkStep()的具体实现代码如下。

(6)函数setAndReturnMarkBit的功能是设置并返回有标记位的对象,具体实现代码如下。

(7)函数markObjectNonNul的功能是标记非空对象,具体实现代码如下。

(8)函数markObject的功能是通过递归算法来标记对象,具体实现代码如下。

任何新的标记对象的地址是低于指定访问的扫描位图的,所以这些对象需要被添加到标记栈。

(9)函数rootMarkObjectVisitor的功能是标记根对象的访问者,具体实现代码如下。

(10)调用函数dvmHeapMarkRootSet标记所有根对象,即负责标记heap中的没有任何引用连接的root对象。其实现代码如下。

(11)函数rootReMarkObjectVisitor的功能是重新标记根对象的访问者,具体实现代码如下。

(12)函数dvmHeapReMarkRootSet的功能是标记根中的所有的引用,具体实现代码如下。

(13)函数scanFields的功能是扫描所有的实例字段,具体实现代码如下。

(14)函数scanStaticFields的功能是扫描类对象中的静态域,具体实现代码如下。

(15)函数scanInterfaces的功能是访问一个类对象的接口,具体实现代码如下。

(16)函数scanClassObject的功能是分别扫描头、静态字段的引用和一个类对象的接口指针。具体实现代码如下。

(17)函数scanArrayObject的功能是扫描所有数组对象的标题。如果数组对象是专门为一个引用类型服务的,则需要扫描其阵列的数据和。具体实现代码如下。

(18)函数referenceClassFlags的功能是返回有关参考子类的标志,具体实现代码如下。

(19)函数isSoftReference、isWeakReference、isFinalizerReference和isPhantomReference的功能是,如果对象是软引用、来自弱引用、派生自FinalizerReference、派生自Phantom Reference,则返回true,具体实现代码如下。

(20)函数enqueuePendingReference的功能是处理排队等待的引用的高优先的线程,具体实现代码如下。

(21)函数dequeuePendingReference的功能是移除引用队列中的一个参考,具体实现代码如下。

(22)函数delayReferenceReferent的功能是根据对象的类型,将其放入相应的待释放队列中。如果对象是fianlizeable对象,则放入finalizerReferences队列中。如果对象是WeakReference对象,则将其放入weakReferences队列中。函数delayReferenceReferent的具体实现代码如下。

(23)函数scanDataObject的功能是扫描对象的各个成员,并标记其所有引用到的对象。具体实现代码如下。

(24)函数scanObject的功能是处理“mark stack”中的每个对象,首先判断对象是保存Java类型信息的类型对象,还是数组对象,还是普通的Java对象,针对这三种对象进行不同的处理。由于finalize对象是普通的Java对象,因此这里只看相应的scanDataObject函数。函数scanObject的具体实现代码如下。(www.daowen.com)

(25)函数processMarkStack的功能是处理需要特殊处理的对象,调用scanObject函数处理“mark stack”中的每个对象。具体实现代码如下。

(26)函数objectSize的功能是计算对象的大小,具体实现代码如下。

(27)函数nextGrayObject的功能是向前扫描标记对象,如果没有标记对象,在这一区域返回NULL。函数nextGrayObject的具体实现代码如下。

(28)函数scanDirtyCards的功能是在开始和结束范围之间扫描“脏卡片”。在垃圾收集时,需要对与老一代中卡片相关联的标记位进行检查,对脏的卡片扫描以寻找对年轻代有引用的对象。函数scanDirtyCards的具体实现代码如下。

而函数scanGrayObjects的功能是实现具体扫描工作,具体实现代码如下。

(29)函数scanBitmapCallback的功能是扫描每个对象位图中的回调,即当前的被设置为对应于位图中的位的下一个最低地址的地址。函数scanBitmapCallback的具体实现代码如下。

(30)根据上一个函数给出的根对象位图,调用函数dvmHeapScanMarkedObjects对每一个与根相关的位图进行计算,如果这个根对象有被引用,就标记为使用。这个过程是递归调用的过程,从根开始不断重复地对子树进行标记的过程。函数dvmHeapScanMarkedObjects的具体实现代码如下。

而函数dvmHeapReScanMarkedObjects的功能是重复扫描标记的对象,具体实现代码如下。

(31)函数clearReference的功能是清除参考区域,具体实现代码如下。

(32)函数preserveSomeSoftReferences的功能是保留一些软引用,具体实现代码如下。

(33)函数clearWhiteReferences的功能是清除白色参考引用,具体实现代码如下。

(34)函数enqueueFinalizerReferences的功能是通过JNI方式将finalize对象的引用传递到Java端的一个java.lang.ref.ReferenceQueue中,具体实现代码如下。

(35)函数dvmHeapProcessReferences的功能是在垃圾对象收集完毕后,将finalize队列从虚拟机的本地端传递到Java端。函数dvmHeapProcessReferences的具体实现代码如下。

(36)函数dvmEnqueueClearedReferences的功能是让一个清除列表引用托管堆,具体实现代码如下。

(37)调用函数dvmHeapFinishMarkStep回收已经删除对象的内存,可以调用堆管理函数改变目前堆使用的内存,并整理内存,这样就可以得到更多空闲的内存了。函数dvmHeapFinishMarkStep的具体实现代码如下。

(38)函数sweepBitmapCallback的功能是扫描位图回调,具体实现代码如下。

(39)函数sweepWeakJniGlobals的功能是扫描弱全局JNI,具体实现代码如下。

(40)调用函数dvmHeapSweepUnmarkedObjects清除未曾标记的对象,也就是删除没有再使用的对象。函数dvmHeapSweepUnmarkedObjects的具体实现代码如下。

(41)调用函数dvmHeapHandleReferences处理Java类对象的引用类型。在此主要处理如下三个直接子类。

SoftReference:封装了对引用目标的“软引用”。

WeakReference:封装了对引用目标的“弱引用”。

PhantomReference:封装了对引用目标的“影子引用”。强引用禁止引用目标被垃圾收集,而软引用、弱引用和影子引用不禁止。

函数dvmHeapHandleReferences的具体实现代码如下。

(42)调用函数dvmHeapScheduleFinalizations调用未曾标记的对象,让每一个对象最后的删除动作可以运行,以便后面从内存里把对象删除,相当于对象的析构作用。函数dvmHeapScheduleFinalizations的具体实现代码如下。

上述算法函数的整个过程,就是Dalvik虚拟机的整个标记和删除的算法过程,实际的代码会相当复杂,算法是相对比较清楚的,就是细节、时间方面要求相当严格,否则乱删除还在使用的对象,会导致整个虚拟机运行出错。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈