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
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章