8

我有一个 Windows MFC 应用程序:

(1) 加载 JVM ( JNI_CreateJavaVM())

(2) 将主线程附加到 JVM ( AttachCurrentThread())

(3) 加载一些Java类和方法(FindClass()GetMethodID()/ GetStaticMethodID()

(4) 注册一些本机回调供 Java 代码使用 ( RegisterNatives())

(5) 从 JVM 中分离线程 ( DetachCurrentThread())

(6) 销毁 JVM ( DestroyJavaVM())

每次我运行应用程序时,上述所有功能都会成功。我知道他们成功了,因为除上述之外,我还与应用程序交互并成功调用 Java 静态方法,并且这些 Java 方法成功调用了我的本机回调。我的应用程序正常退出,并且可以肯定预期的 Java 函数和本机回调已经执行。

但是,每隔一次我运行应用程序时,调用JNI_CreateJavaVM()都会失败(不填充JavaVM *)。 应用程序运行之间绝对没有任何变化。我只需运行一次(成功,即使除了上述 6 个步骤之外什么都不做),优雅地退出,再次运行,它来回失败。来回成功/失败没有例外——我可以运行它几十次,它每隔一次就会在成功和失败之间精确振荡JNI_CreateJavaVM()

如有必要,我将粘贴更多代码。但是,我希望有人对我提供的内容有所了解。(注意:这是一个 BCGSoft MFC 属性表应用程序,尽管我非常怀疑这很重要。)

4

1 回答 1

4

看起来您遇到了这个可能永远无法修复的错误(在此处重述)。

尽管它的名字,DestroyJavaVM()实际上并没有破坏JVM。它所做的是向 JVM 发出它应该关闭的信号,但 JVM 实际上会等待,直到除主线程之外的所有线程都停止后,它才会真正关闭。事实上,即便如此,它本身也没有完全清理,正如文档所述(相当隐晦):“但是,JDK/JRE 仍然不支持 VM 卸载。”

另外,我担心您的第 2 步“将主线程附加到 JVM”。您不需要将创建 JVM 的线程附加到 JVM,也不能分离该线程。如果您真的这样做,那么很可能这就是您的系统混乱的原因。(创建 JVM 的线程是 JVM 的“主”线程。如果它们需要访问它,您只需要将其他本机线程附加/分离到 JVM。)

顺便说一句,JNI_CreateJavaVM()成功时返回 0,而你说它在“失败”时返回 0,那么它在什么意义上失败了?您使用的是哪个 JVM(版本、供应商)?

于 2012-05-17T06:38:10.403 回答