kvm垃圾收集-005

本文介绍garbageCollectForReal中的第3步–markWeakPointerLists,第4步–markWeakReferences.

markWeakPointerLists

其代码如下:

static void
markWeakPointerLists()
{
    WEAKPOINTERLIST list;
    /*  1. 保存本地方法指针 */
    cell* currentNativeLp = NULL;
    if (CurrentThread) {
        currentNativeLp = CurrentThread->nativeLp;
    }

    // 2. 遍历WeakPointers
    for (list = WeakPointers; list != NULL; list = list->gcReserved) {
        void (*finalizer)(INSTANCE_HANDLE) = list->finalizer;
        cellOrPointer *ptr = &list->data[0];
        cellOrPointer *endPtr = ptr + list->length;

        for (; ptr < endPtr; ptr++) {
            cell* object = ptr->cellp;
            if (object != NULL) {
            	// 如果该对象不是存活的,则调用finalizer方法
                if (!ISKEPT((object)[-HEADERSIZE])) {
                    ptr->cellp = NULL;
                    if (finalizer) {
                      
                        if (CurrentThread) {
                            CurrentThread->nativeLp = (cell *)&object;
                        }

                       
                        finalizer((INSTANCE_HANDLE)&object);
                    }

                }
            }
        }
    }

    /*  3. 恢复本地方法指针 */
    if (CurrentThread) {
        CurrentThread->nativeLp = currentNativeLp;
    }
}

此处不难理解.其WeakPointers的定义如下:

struct weakPointerListStruct { 
    long length;
    struct weakPointerListStruct* gcReserved; // 链表结构
    void (*finalizer)(INSTANCE_HANDLE);
    cellOrPointer data[1];  
};

typedef struct weakPointerListStruct* WEAKPOINTERLIST;
WEAKPOINTERLIST WeakPointers; 

而此处的WeakPointers是在markChildren中构建的:

 case GCT_WEAKPOINTERLIST:
       // 此处使用了头插法构建链表   
		((WEAKPOINTERLIST)object)->gcReserved = WeakPointers;
		WeakPointers = (WEAKPOINTERLIST)object;
		break;

而具有GCT_WEAKPOINTERLIST类型的object是在registerCleanup中创建的.代码如下:

void registerCleanup(INSTANCE_HANDLE instanceH, CleanupCallback cb) {
    int i;
    WEAKPOINTERLIST list = NULL;
    cell  **ptr, **endptr;

    /* Check each known root to see if it is for this callback (cb) 1. 检查是否存在*/
    for (i = CleanupRoots->length - 1; i >= 0; i--) {
        list = (WEAKPOINTERLIST)CleanupRoots->data[i].charp;
        if (list->finalizer == cb) {
            break;
        }
    }
    if (i < 0) {
        int size;
        /* Didn't find an array for this function, allocate a new one  2. 如果不存在,就重新创建 */
        i = CleanupRoots->length;
        if (i >= CLEANUP_ROOT_SIZE) {// 2.1 如果超过长度的话,则抛出异常
            /* TBD: expand roots if not enough */
            fatalError(KVM_MSG_ERROR_TOO_MANY_CLEANUP_REGISTRATIONS);
        }
        // StructSizeInCells(weakPointerListStruct)+((3)-1)
        size = SIZEOF_WEAKPOINTERLIST(CLEANUP_ARRAY_SIZE); // CLEANUP_ARRAY_SIZE = 3
        list = (WEAKPOINTERLIST)callocObject(size, GCT_WEAKPOINTERLIST);
        list->length = CLEANUP_ARRAY_SIZE;
        list->finalizer = cb;
        list->data[CLEANUP_ARRAY_SIZE - 1].cellp = (cell *)unhand(instanceH); // 保存instance

        /* Insert the function pointer into this new array 3. 添加到CleanupRoots 中 */
        CleanupRoots->data[i].cellp = (cell *)list;
        CleanupRoots->length = i + 1;
        return;
    }

    /* We want to insert "instance" into the i-th element of CleanupRoots,
     * which happens to be "list".
     */

    /* Skip over 0th entry used by GC, 1st is function pointer  data[0]是被gc所使用的*/
    ptr = &list->data[0].cellp;
    endptr = ptr + list->length;

    //
    for ( ; ptr < endptr; ptr++) {
        if (*ptr == NULL) {
            *ptr = (cell *)unhand(instanceH);
            if (EXCESSIVE_GARBAGE_COLLECTION) { 
                /* Make sure people realize that this function really
                 * can cause an allocation to happen */
                garbageCollect(0);
            }
            return;
        }
    }

    /* We did not find an empty list.  We need to make the list larger and
     * copy the old one into the new one
     * 如果没有找到空的,则需要重新分配一个大的
     */
    {
        int oldLength = list->length;
        int newLength = oldLength + CLEANUP_ARRAY_GROW;//3
        WEAKPOINTERLIST newList =
            (WEAKPOINTERLIST)callocObject(SIZEOF_WEAKPOINTERLIST(newLength),
                                          GCT_WEAKPOINTERLIST);
        newList->length = newLength;
        newList->finalizer = cb;
        list = (WEAKPOINTERLIST)CleanupRoots->data[i].cellp; /*may have moved*/
        CleanupRoots->data[i].cellp = (cell *)newList;

        /* Update original elements of list, and insert the new element
         * at the end.
         */
        memcpy(newList->data, list->data, oldLength << log2CELL);
        newList->data[newLength - 1].cellp = (cell *)unhand(instanceH);
    }
}

而registerCleanup方法是在解释器处理new字节码时处理的.代码如下:

if (newObject != NULL) {
            if (thisClass->finalizer != NULL) {
                /* register finalizer for this object */
                registerCleanup((INSTANCE_HANDLE)&newObject,
                                (CleanupCallback)thisClass->finalizer);
            }
            pushStackAsType(INSTANCE, newObject);
            ip += 3;
}

markWeakReferences

此处的代码如下:

static void
markWeakReferences()
{
    WEAKREFERENCE thisRef;

   
    for (thisRef = WeakReferences; thisRef != NULL; thisRef = thisRef->gcReserved) {

        /*  如果引用的对象不会存活对象,则清除引用*/
        cell* referent = (cell*)thisRef->referent;
        if (referent != NULL && !ISKEPT((referent)[-HEADERSIZE]))
            thisRef->referent = NULL;
    }
}

WEAKREFERENCE定义如下:

struct weakReferenceStruct {
    COMMON_OBJECT_INFO(INSTANCE_CLASS)
    cell* referent;
    struct weakReferenceStruct* gcReserved;
};

而WEAKREFERENCE是在markChildren中构建的:

 case GCT_WEAKREFERENCE: {
            /
            checkMonitorAndMark((OBJECT)object);

            /* Push this object onto the linked list of weak refs */
            ((WEAKREFERENCE)object)->gcReserved = WeakReferences;
            WeakReferences = (WEAKREFERENCE)object;

            /* NOTE: We don't mark the 'referent' field of the */
            /* weak reference object here, because we want to */
            /* keep the referent alive only if there are */
            /* strong references to it. */
            break;
        }

而具有GCT_WEAKPOINTERLIST类型的object是在WeakReference#initializeWeakReference中创建的.该方法为本地方法,代码如下:

 private native void initializeWeakReference();
 
 void Java_java_lang_ref_WeakReference_initializeWeakReference(void)
{
    /* This implementation is very KVM-specific: */

    /* We've added a new garbage collection (GCT) */
    /* type specifically for weak references. */

    /* We need to convert the object from a regular */
    /* instance (GCT_INSTANCE) to GCT_WEAKREFERENCE. */
    /* We do this by updating the header word of the */
    /* garbage collector. */

    /* First, read the 'this' pointer */
    cell* instance = popStackAsType(cell*);

    /* Find the garbage collector header word location */
    cell* header = instance-HEADERSIZE;

    /* Read the header and blow away old GCT type info */
    cell headerData = *header & ~TYPEMASK;

    /* Store new GCT type info into the header */
    *header = headerData | (GCT_WEAKREFERENCE << TYPE_SHIFT); // 将所引用的对象的对象头设置为GCT_WEAKREFERENCE
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值