void dvmHeapScanMarkedObjects(void)
{
GcMarkContext *ctx = &gDvm.gcHeap->markContext;
assert(ctx->finger == NULL);
/* The bitmaps currently have bits set for the root set.
* Walk across the bitmaps and scan each object.
*/
//ctx->bitmap用来标识是否可达
//广度优先遍历所有对象是否可达
dvmHeapBitmapScanWalk(ctx->bitmap, scanBitmapCallback, ctx);
ctx->finger = (void *)ULONG_MAX;
/* We've walked the mark bitmaps. Scan anything that's
* left on the mark stack.
*/
processMarkStack(ctx);
}
void dvmHeapBitmapScanWalk(HeapBitmap *bitmap,
BitmapScanCallback *callback, void *arg)
{
assert(bitmap != NULL);
assert(bitmap->bits != NULL);
assert(callback != NULL);
uintptr_t end = HB_OFFSET_TO_INDEX(bitmap->max - bitmap->base);
uintptr_t i;
for (i = 0; i <= end; ++i) {
unsigned long word = bitmap->bits[i];
if (UNLIKELY(word != 0)) {
unsigned long highBit = 1 << (HB_BITS_PER_WORD - 1);
//找出实例基地址
uintptr_t ptrBase = HB_INDEX_TO_OFFSET(i) + bitmap->base;
void *finger = (void *)(HB_INDEX_TO_OFFSET(i + 1) + bitmap->base);
while (word != 0) {
//最高位0的个数
const int shift = CLZ(word);
//shift可能是object的个数
//难道bits里面存放的是每隔class对象的个数,借此找到对象的地址???
//object地址
Object *obj = (Object *)(ptrBase + shift * HB_OBJECT_ALIGNMENT);
(*callback)(obj, finger, arg);
//清0操作
word &= ~(highBit >> shift);
}
end = HB_OFFSET_TO_INDEX(bitmap->max - bitmap->base);
}
}
}
static void scanObject(const Object *obj, GcMarkContext *ctx)
{
assert(obj != NULL);
assert(obj->clazz != NULL);
if (obj->clazz == gDvm.classJavaLangClass) {
scanClassObject(obj, ctx);
} else if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
scanArrayObject(obj, ctx);
} else {
scanDataObject(obj, ctx);
}
}
static void scanClassObject(const Object *obj, GcMarkContext *ctx)
{
assert(obj != NULL);
assert(dvmIsClassObject(obj));
assert(ctx != NULL);
markObject((const Object *)obj->clazz, ctx);
const ClassObject *asClass = (const ClassObject *)obj;
if (IS_CLASS_FLAG_SET(asClass, CLASS_ISARRAY)) {
markObject((const Object *)asClass->elementClass, ctx);
}
/* Do super and the interfaces contain Objects and not dex idx values? */
//当前类的状态
if (asClass->status > CLASS_IDX) {
markObject((const Object *)asClass->super, ctx);
}
markObject((const Object *)asClass->classLoader, ctx);
//扫描域和静态域
scanFields(obj, ctx);
scanStaticFields(asClass, ctx);
if (asClass->status > CLASS_IDX) {
scanInterfaces(asClass, ctx);
}
}
static void scanDataObject(const Object *obj, GcMarkContext *ctx)
{
assert(obj != NULL);
assert(obj->clazz != NULL);
assert(ctx != NULL);
markObject((const Object *)obj->clazz, ctx);
//扫描字段
scanFields(obj, ctx);
//如果是个引用
if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISREFERENCE)) {
delayReferenceReferent((Object *)obj, ctx);
}
}
void dvmHeapProcessReferences(Object **softReferences, bool clearSoftRefs,
Object **weakReferences,
Object **finalizerReferences,
Object **phantomReferences)
{
assert(softReferences != NULL);
assert(weakReferences != NULL);
assert(finalizerReferences != NULL);
assert(phantomReferences != NULL);
/*
* Unless we are in the zygote or required to clear soft
* references with white references, preserve some white
* referents.
*/
//部分时候会保存soft refs
if (!gDvm.zygote && !clearSoftRefs) {
preserveSomeSoftReferences(softReferences);
}
/*
* Clear all remaining soft and weak references with white
* referents.
*/
//处理ref
clearWhiteReferences(softReferences);
clearWhiteReferences(weakReferences);
/*
* Preserve all white objects with finalize methods and schedule
* them for finalization.
*/
enqueueFinalizerReferences(finalizerReferences);
/*
* Clear all f-reachable soft and weak references with white
* referents.
*/
//Finalization改变了一些object的状态,重新处理soft ref和weak ref
clearWhiteReferences(softReferences);
clearWhiteReferences(weakReferences);
/*
* Clear all phantom references with white referents.
*/
clearWhiteReferences(phantomReferences);
/*
* At this point all reference lists should be empty.
*/
}
static void clearWhiteReferences(Object **list)
{
assert(list != NULL);
GcMarkContext *ctx = &gDvm.gcHeap->markContext;
size_t referentOffset = gDvm.offJavaLangRefReference_referent;
while (*list != NULL) {
Object *ref = dequeuePendingReference(list);
Object *referent = dvmGetFieldObject(ref, referentOffset);
if (referent != NULL && !isMarked(referent, ctx)) {
/* Referent is white, clear it. */
clearReference(ref);
//soft ref队列,可用于检测soft ref是否被回收
if (isEnqueuable(ref)) {
enqueueReference(ref);
}
}
}
assert(*list == NULL);
}
Pending_next
//head--last item1--head item2--head item3--head ...... last—head
void dvmHeapSweepSystemWeaks()
{
//清空字符串池
dvmGcDetachDeadInternedStrings(isUnmarkedObject);
/*
一个Dalvik虚拟机线程在执行JNI方法的时候,除了可能需要访问Java层的对象之外,
还可能需要进行一些同步操作,也就是进行MonitorEnter和MonitorExit操作。
注意,MonitorEnter和MonitorExit是Java代码中的同步指令,用来实现synchronized代码块或者函数的。
Dalvik虚拟机需要跟踪在JNI方法中所执行的MonitorEnter操作,
也就是将被Monitor的对象添加到Monitor引用表中去,以便在JNI方法退出时,
可以隐式地进行MonitorExit操作,避免出现不对称的MonitorEnter和MonitorExit操作
*/
//?
dvmSweepMonitorList(&gDvm.monitorList, isUnmarkedObject);
//清理jni中的弱引用
sweepWeakJniGlobals();
}
void dvmHeapSweepUnmarkedObjects(bool isPartial, bool isConcurrent,
size_t *numObjects, size_t *numBytes)
{
uintptr_t base[HEAP_SOURCE_MAX_HEAP_COUNT];
uintptr_t max[HEAP_SOURCE_MAX_HEAP_COUNT];
SweepContext ctx;
HeapBitmap *prevLive, *prevMark;
size_t numHeaps, numSweepHeaps;
numHeaps = dvmHeapSourceGetNumHeaps();
//将heap对象的base和max,copy了
dvmHeapSourceGetRegions(base, max, numHeaps);
if (isPartial) {
assert((uintptr_t)gDvm.gcHeap->markContext.immuneLimit == base[0]);
numSweepHeaps = 1;
} else {
numSweepHeaps = numHeaps;
}
//ctx中object的个数
ctx.numObjects = ctx.numBytes = 0;
ctx.isConcurrent = isConcurrent;
//mark bits和live bits被交换过
//此处又进行了第二次交换
prevLive = dvmHeapSourceGetMarkBits();
prevMark = dvmHeapSourceGetLiveBits();
for (size_t i = 0; i < numSweepHeaps; ++i) {
dvmHeapBitmapSweepWalk(prevLive, prevMark, base[i], max[i],
sweepBitmapCallback, &ctx);
}
*numObjects = ctx.numObjects;
*numBytes = ctx.numBytes;
if (gDvm.allocProf.enabled) {
gDvm.allocProf.freeCount += ctx.numObjects;
gDvm.allocProf.freeSize += ctx.numBytes;
}
}