java - 从 JVM 清除所有加载的类

标签 java c++ 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);

Unloads a Java VM and reclaims its resources. The support for DestroyJavaVM was not complete in JDK/JRE 1.1. As of JDK/JRE 1.1 Only the main thread may call DestroyJavaVM. Since JDK/JRE 1.2, any thread, whether attached or not, can call this function. If the current thread is attached, the VM waits until the current thread is the only non-daemon user-level Java thread. If the current thread is not attached, the VM attaches the current thread and then waits until the current thread is the only non-daemon user-level thread. The JDK/JRE still does not support VM unloading, however.

因此,我无法“创建、破坏、创建、破坏、重复”。 相反,我必须在应用程序的生命周期内创建并保留实例,并且仅在我的应用程序即将关闭时销毁该实例。

这很糟糕,因为如果我想将两个不同的 jar 加载到 JVM 中,我做不到。他们可能有也可能没有同名的类。内存使用量猛增。

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

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

最佳答案

执行此操作的最简单方法是启动一个新进程,然后销毁它并完成。

另一种解决方案是使用 ClassLoader 来加载您希望稍后卸载的类。当一个 ClassLoader 被卸载时,它的所有类都被释放。

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

恕我直言,尝试从 JNI 创建和销毁 JVM 是非常棘手的(尽管不像以前那样棘手),我只会在万不得已时才这样做。有许多方法可以实现您想要的,而且要简单得多。

关于java - 从 JVM 清除所有加载的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28670272/

相关文章:

c++ - 这个typedef是必需的吗?

c++ - 交换不同大小的数组

java - Weblogic 10.3.6 域向导无法创建 JVM

java - com.ibm.jsse2.util 未找到可信证书

java - 在 Java 中激活其他进程的窗口

java - 为什么这个 long 溢出到 -1,而不是类型的最小值?

java - JDK11之后WSIMPORT在哪里

c++ - QT中如何在消息框中显示图标?

java - Jsoup - 如何选择元素内的元素

java - 如何使用 pkcs11 包装器 ECDSA key 签署 CSR