通过上面的学习,了解了垃圾回收的原理和过程。那么Dalvik虚拟机是什么时候进行垃圾回收呢?要回答这个问题,那么得继续分析代码,继续进入下面的学习。其实,垃圾回收主要有两种方式,一种是虚拟机线程自动进行的,一种是手动进行的。现在先来学习自动进行的方式,所谓自动方式,就是虚拟机创建一个线程,这个线程定时进行。虚拟机在初始化时,就进行创建这个线程,如下的代码:
if(gDvm.zygote){
if(!dvmInitZygote())
gotofail;
} else{
if(!dvmInitAfterZygote())
gotofail;
}
在上面这段代码里调用函数dvmInitAfterZygote,在这个函数里就会调用函数dvmSignalCatcherStartup来创建垃圾回收线程,这个函数的代码如下:
booldvmSignalCatcherStartup(void)
{
gDvm.haltSignalCatcher= false;
if(!dvmCreateInternalThread(&gDvm.signalCatcherHandle,
"SignalCatcher", signalCatcherThreadStart,NULL))
returnfalse;
returntrue;
}
通过上面的这段代码,就可以看到线程运行函数是signalCatcherThreadStart,在这个函数里就会调用函数dvmCollectGarbage来进行垃圾回收。代码如下:
voiddvmCollectGarbage(bool collectSoftReferences)
{
dvmLockHeap();
LOGVV("ExplicitGC\n");
dvmCollectGarbageInternal(collectSoftReferences);
dvmUnlockHeap();
}
在这个函数主要通过锁来锁住多线程访问的堆空间相关对象,然后直接就调用函数dvmCollectGarbageInternal来进行垃圾回收过程了,也就调用上面标记删除算法的函数。
另一种方式通过调用运行库的GC来回收,如下:
/*
* public void gc()
*
* Initiate a gc.
*/
staticvoidDalvik_java_lang_Runtime_gc(constu4* args,JValue*pResult)
{
UNUSED_PARAMETER(args);
dvmCollectGarbage(false);
RETURN_VOID();
}
在这里也是调用函数dvmCollectGarbage来进行垃圾回收。手动的方式适合当需要内存,但线程又没有调用时进行。