繁体   English   中英

从JVM清除所有已加载的类

[英]Clearing all loaded classes from the JVM

我通过JNI创建了一个JVM,如下所示:

bool JavaVM_Create(Jvm* &ptr, int argc, const char* argv[])
{
    bool result = false;
    if (!ptr && argc > 0)
    {
        ptr = new Jvm();
        JavaVMInitArgs jvm_args;
        JavaVMOption* options = new JavaVMOption[argc];

        for (int i = 0; i < argc; ++i)
        {
            options[i].optionString = const_cast<char*>(argv[i]);
        }

        JNI_GetDefaultJavaVMInitArgs(&jvm_args);

        jvm_args.version = JNI_VERSION_1_8;
        jvm_args.nOptions = 2;
        jvm_args.options = options;
        jvm_args.ignoreUnrecognized = false;

        result = true;

        jint num_vms = 0;
        JavaVM* vms[5] = {0};
        if (JNI_GetCreatedJavaVMs(vms, 5, &num_vms) == JNI_OK)
        {
            if (num_vms > 0)
            {
                ptr->vm = vms[0];
                ptr->vm->AttachCurrentThread();
                delete[] options;
                return result;
            }
        }

        if (!ptr->createJVM(&jvm_args))
        {
            result = false;
        }
        delete[] options;
    }
    return result;
}

void JavaVM_Free(Jvm* &ptr)
{
    if (ptr && ptr->vm)
    {
        ptr->vm->DetachCurrentThread();
        ptr->vm->DestroyJavaVM();
    }

    delete ptr;
    ptr = nullptr;
}

我使用JNI_GetCreatedJavaVMs的原因是为了修复JDK中指出以下错误:

jint DestroyJavaVM(JavaVM * vm);

卸载Java VM并回收其资源。 在JDK / JRE 1.1中,对DestroyJavaVM的支持不完整。 从JDK / JRE 1.1开始,只有主线程可以调用DestroyJavaVM。 从JDK / JRE 1.2开始,任何线程(无论是否连接)都可以调用此函数。 如果连接了当前线程,则VM会等待直到当前线程是唯一的非守护程序用户级Java线程。 如果未附加当前线程,则VM会附加当前线程,然后等待直到当前线程是唯一的非守护程序用户级线程。 但是,JDK / JRE仍然不支持VM卸载

因此,我无法“创建,销毁,创建,销毁,重复”。 取而代之的是,我必须创建,在应用程序的生命周期内保留实例,并仅在应用程序即将关闭时销毁该实例。

这很烂,因为如果我要将两个不同的jar加载到JVM中,就不能这样做。 它们可能具有或不具有相同名称的类。 内存使用率飞速增长。

因此,我试图找到一种方法来完全卸载JVM(销毁它)或卸载所有已加载的类(将其重置)。

有什么想法或解决方案吗?

最简单的方法是启动一个新进程,然后销毁已完成的进程。

另一个解决方案是使用ClassLoader加载要稍后卸载的类。 卸载ClassLoader时,将释放其所有类。

顺便说一句,您可以一次加载多个ClassLoader,甚至可以加载同一类的不同版本。

恕我直言,尝试从JNI创建和销毁JVM非常棘手(尽管不像以前那样棘手),我只能做为最后的选择。 有许多方法可以实现所需的目标,这要简单得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM