Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JNI-有没有办法让JVM调用JNI_OnUnload?_Java_C++_Java Native Interface_Shared Libraries_Jnienv - Fatal编程技术网

Java JNI-有没有办法让JVM调用JNI_OnUnload?

Java JNI-有没有办法让JVM调用JNI_OnUnload?,java,c++,java-native-interface,shared-libraries,jnienv,Java,C++,Java Native Interface,Shared Libraries,Jnienv,关于这方面的信息非常少,例如2006年,并且放弃优雅地发布JNI资源 JNI_OnUnload()用于在JVM中不再需要本机功能时释放资源(“尤其是全局引用”)。本机库的加载方式如下 static { System.loadLibrary("mylibjni"); // on Linux this translates to "libmylibjni.so" } 。。。但是Java没有提供明确的卸载方式 发生了什么:在我的库中,由于没有得到清理的机会,库最终会卸载(我不知道什么时候卸载

关于这方面的信息非常少,例如2006年,并且放弃优雅地发布JNI资源

JNI_OnUnload
()用于在JVM中不再需要本机功能时释放资源(“尤其是全局引用”)。本机库的加载方式如下

static {
    System.loadLibrary("mylibjni"); // on Linux this translates to "libmylibjni.so"
}
。。。但是Java没有提供明确的卸载方式

发生了什么:在我的库中,由于没有得到清理的机会,库最终会卸载(我不知道什么时候卸载,请参见下面的调用堆栈),但是太晚了,这会触发一些拥有JNI全局引用的全局变量调用
DeleteGlobalRef
,失败:

# JRE version: OpenJDK Runtime Environment (10.0.2+13) (build 10.0.2+13)
# Java VM: OpenJDK 64-Bit Server VM (10.0.2+13, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# C  [libblahjni.so+0x9a7e6]  JNIEnv_::DeleteGlobalRef(_jobject*)+0x14
深入研究,这是因为在执行卸载的线程上没有
JNIEnv
(我在
thread\u local
的基础上缓存env)。当时尝试检索Env没有起作用-我尝试使用
JavaVM::GetEnv
JavaVM::AttachCurrentThread
并且似乎即使附加工作正常,
JavaVM::GetEnv
仍然返回
JNI\u-edeached(-2)
。因此,在JVM生命周期中,附加/拥有env可能已经太晚了

我还尝试了其他一些东西——根据上面2006年的文章,我在Java中尝试了
System.runFinalizersOnExit(true)
,但运气不好。即使我确实看到正在调用终结器(与不调用runFinalizers时相反,请参见下面的输出),
JNI\u onnload
仍然没有被调用

Checked JNI functions are being used to validate JNI usage
[Dynamic-linking native method java.lang.Shutdown.runAllFinalizers ... JNI]
Checked JNI functions are being used to validate JNI usage
[Dynamic-linking native method java.lang.Shutdown.halt0 ... JNI]
作为最后一条信息,lib卸载调用堆栈如下所示。我不明白它是从哪里来的。我使用的是最新的ArchLinux,Java10,如果有必要的话,我使用的是Docker。我想从原则上解决优雅的退出问题,因为这样可以让您很容易地发现项目生命周期后期出现的问题

[Dynamic-linking native method java.lang.Shutdown.runAllFinalizers ... JNI]
Checked JNI functions are being used to validate JNI usage
[Dynamic-linking native method java.lang.Shutdown.halt0 ... JNI]
 0# (some more code of my own ommitted at the top of the stack)
 1# std::_Optional_payload<...
 2# std::_Optional_base<...
 3# std::optional<...>::~optional() in /orion/mpf-jni/Debug/libmylibjni.so
 4# 0x00007FDCEC5E845C in /usr/lib/libc.so.6
 5# 0x00007FDCEC5E858E in /usr/lib/libc.so.6
 6# 0x00007FDCEB919B89 in /usr/lib/jvm/java-10-openjdk/lib/server/libjvm.so
 7# 0x00007FDCEBDF58C6 in /usr/lib/jvm/java-10-openjdk/lib/server/libjvm.so
 8# 0x00007FDCEBDF5346 in /usr/lib/jvm/java-10-openjdk/lib/server/libjvm.so
 9# 0x00007FDCEBDF2770 in /usr/lib/jvm/java-10-openjdk/lib/server/libjvm.so
10# 0x00007FDCEBDF3D2F in /usr/lib/jvm/java-10-openjdk/lib/server/libjvm.so
11# 0x00007FDCEBDF3FBE in /usr/lib/jvm/java-10-openjdk/lib/server/libjvm.so
12# 0x00007FDCEBC0558A in /usr/lib/jvm/java-10-openjdk/lib/server/libjvm.so
13# 0x00007FDCEC378A9D in /usr/lib/libpthread.so.0
14# clone in /usr/lib/libc.so.6
  1447612069173.971  Fatal| could not get JVM env object for JNI version [65540], error [-2]
[动态链接本机方法java.lang.Shutdown.runAllFinalizers…JNI]
选中的JNI函数用于验证JNI的使用情况
[动态链接本机方法java.lang.Shutdown.halt0…JNI]
0#(我自己的一些代码被写入堆栈顶部)
1#标准::_可选_有效载荷