kvm终止流程

本文介绍KVM的终止流程.其是在StartJVM方法中调用的.代码如下:

int StartJVM(int argc, char* argv[])
{
    volatile int returnValue = 0;

    /* Ensure that we have a class to run 必须提供要运行的类名 */
    if (argc <= 0 || argv[0] == NULL) {
        AlertUser(KVM_MSG_MUST_PROVIDE_CLASS_NAME);
        return -1;
    }

    // 启动KVM
    returnValue = KVM_Start(argc, argv);
    KVM_Cleanup();
    return returnValue;
}

而KVM_Cleanup的代码如下:

void KVM_Cleanup()
{
#if ENABLE_JAVA_DEBUGGER
    if (vmDebugReady) {
        setEvent_VMDeath();
        CloseDebugger();
        clearAllBreakpoints();
    }
#endif
    FinalizeVM();// 此处为宏
    FinalizeInlineCaching(); // 释放InlineCache
    FinalizeNativeCode(); // 释放本地代码,在unix环境为空方法
    FinalizeJavaSystemClasses(); // 释放类
    FinalizeClassLoading();// 释放ClassPathTable
    FinalizeMemoryManagement();// 释放堆
    DestroyROMImage();// 此处为宏
    FinalizeHashtables(); // 释放UTFStringTable,InternStringTable,ClassTable
}

此处的有效步骤如下:

  1. 释放InlineCache,这点在kvm-inlineCache
  2. 释放类
  3. 释放ClassPathTable
  4. 释放堆
  5. 释放UTFStringTable,InternStringTable,ClassTable

释放类

代码如下:

void FinalizeJavaSystemClasses()
{
    if (ROMIZING) {
        FinalizeROMImage();
        FOR_ALL_CLASSES(clazz)
            /* Remove any class monitors */
            if (OBJECT_HAS_MONITOR(clazz)) {// 1. 如果对象有锁,则清空锁对象
                clearObjectMonitor((OBJECT)clazz);
            }
            if (!IS_ARRAY_CLASS(clazz)) {
                /* Reset the state of the class to be its initial state.
                 * The ACC_ROM_NON_INIT_CLASS says that neither this class nor
                 * any of its superclasses has a <clinit> method
                 */
                INSTANCE_CLASS iclazz = ((INSTANCE_CLASS)clazz);
                setClassInitialThread(iclazz, NULL); // 设置锁对象为Null
                setClassStatus(iclazz,
                     (iclazz->clazz.accessFlags & ACC_ROM_NON_INIT_CLASS) ?
                              CLASS_READY : CLASS_VERIFIED); // 设置class状态
            }
        END_FOR_ALL_CLASSES
    }
}

关于释放锁的详细内容,后续文章介绍.

释放ClassPathTable

代码如下:

void FinalizeClassLoading()
{
    int paths = ClassPathTable->length;
    int i;
    for (i = 0; i < paths; i++) {
        CLASS_PATH_ENTRY entry =
            (CLASS_PATH_ENTRY)ClassPathTable->data[i].cellp;
        if (entry->type == 'j') { // 如果是jar包,则需要关闭
            closeJARFile(&entry->u.jarInfo);
        }
    }
}

void
closeJARFile(JAR_INFO entry)
{
#if JAR_FILES_USE_STDIO
    fclose((FILE *)entry->u.jar.file);
#endif
}

关于这点,kvm中的class path支持目录,jar包.此处是对jar包的特殊处理.

释放堆

代码如下:

void FinalizeMemoryManagement(void) {
    int i;
    cellOrPointer *ptr, *endPtr;

    /* When memory finalization is being performed */
    /* the VM no longer has a CurrentThread.       */
    /* We need to fake it in order to support the  */
    /* code below. */
    if (CurrentThread == NULL) {
        CurrentThread = MainThread;
    }

    /* Check each known root to see if there are any instances
     * to callback this callback (cb)
     * 1. 调用finalizer方法
     */
    for (i = CleanupRoots->length - 1; i >= 0; i--) {
        WEAKPOINTERLIST list = (WEAKPOINTERLIST)CleanupRoots->data[i].cellp;
        if (list != NULL) {
            void (*finalizer)(INSTANCE_HANDLE) = list->finalizer;
            if (finalizer != NULL) {// 调用finalizer方法
                ptr = &list->data[0];
                endPtr = ptr + list->length;
                for ( ; ptr < endPtr; ptr++) {
                    INSTANCE object = (INSTANCE)(ptr->cellp);
                    if (object != NULL) {
                        
                        /*  调用finalizer方法  */
                        finalizer((INSTANCE_HANDLE)&object);
                    }
                }
                /* Reset 'nativeLp' after calling all finalizers */ 
                CurrentThread->nativeLp = NULL;
            }
        }
    }

    // 2. 清空GlobalRoots
    ptr = &GlobalRoots[0];
    endPtr = ptr + GlobalRootsLength;

    for ( ; ptr < endPtr; ptr++) {
        *(ptr->cellpp) = NULL;
    }

    // 3. 释放heap
    FinalizeHeap();

    if (USESTATIC) {// 此处默认不执行
        FinalizeStaticMemory();
    }
}


void FinalizeHeap(void)
{
    freeHeap(TheHeap);
}

#define freeHeap(x) free(x)

同样,关于finalizer方法,也是后文介绍(此处有一处不解,故不敢乱写…).

释放UTFStringTable,InternStringTable,ClassTable

此处代码如下:

void FinalizeHashtables() { 
    if (!ROMIZING) { 
        UTFStringTable = NULL;
        InternStringTable = NULL;
        ClassTable = NULL;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值