英文:
How to find native libraries in a JDK 17 application that are used via JNI?
问题
我已经分析了我的Java应用程序,并知道它在本地代码中存在内存泄漏问题,但不在应用程序自己的Java源代码中。我正在尝试确定可能有问题的依赖关系或依赖关系。
在JDK的早期版本中,你可以使用类似下面的代码在Java应用程序中找到本地库:
public class ClassScope {
private static final java.lang.reflect.Field LIBRARIES;
static {
LIBRARIES = ClassLoader.class.getDeclaredField("loadedLibraryNames");
LIBRARIES.setAccessible(true);
}
public static String[] getLoadedLibraries(final ClassLoader loader) {
final Vector<String> libraries = (Vector<String>) LIBRARIES.get(loader);
return libraries.toArray(new String[] {});
}
}
final String[] libraries = ClassScope.getLoadedClasses(ClassLoader.getSystemClassLoader());
然而,在JDK 9之后的版本中,如果你尝试这样做,你会收到警告,表示从Java 12开始将撤销这种访问权限:
警告:发生了非法的反射访问操作
警告:非法的反射访问由<class>(文件:<文件>)对方法|构造函数
警告:请考虑将此报告给<文件>的维护者
警告:使用--illegal-access=warn启用进一步的非法反射访问操作的警告
警告:所有非法访问操作将在将来的版本中被拒绝
在JDK 17中,该字段已被完全移除:
在类Ljava/lang/ClassLoader中没有名为loadedLibraryNames的字段;
所以,在JDK 17应用程序中,有哪些选项可以用来识别通过JNI使用的本地库呢?
英文:
I have profiled my Java application and know that it contains a memory leak in native code but not in the application's own Java source code. I'm trying to identify the dependency or dependencies that might be at fault.
Back in earlier versions of the JDK, you could find native libraries in a Java app with something like this:
public class ClassScope {
private static final java.lang.reflect.Field LIBRARIES;
static {
LIBRARIES = ClassLoader.class.getDeclaredField("loadedLibraryNames");
LIBRARIES.setAccessible(true);
}
public static String[] getLoadedLibraries(final ClassLoader loader) {
final Vector<String> libraries = (Vector<String>) LIBRARIES.get(loader);
return libraries.toArray(new String[] {});
}
}
final String[] libraries = ClassScope.getLoadedClasses(ClassLoader.getSystemClassLoader());
However, if you try this on JDKs after 9, you get warned that this access will be revoked from Java 12 om:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by <class> (file:<file>) to method|constructor
WARNING: Please consider reporting this to the maintainers of <file>
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
And in JDK 17 the field has been removed completely:
No field loadedLibraryNames in class Ljava/lang/ClassLoader;
So, in a JDK 17 app, what options are there to identify native libraries used via JNI?
答案1
得分: 2
你可以使用-Xlog:library=trace
虚拟机标志来打印有关加载的库和符号查找的信息。例如:
> java '-Xlog:library=info' Main
[0.011s][info][library] Loaded library jsvml.dll, handle 0x00007ffbd4ab0000
[0.052s][info][library] Failed to find _JNI_OnLoad_jimage@8 in library with handle 0x00007ff6a9610000
[0.052s][info][library] Failed to find JNI_OnLoad_jimage in library with handle 0x00007ff6a9610000
[0.053s][info][library] Loaded library C:\Program Files\Java\jdk-17\bin\jimage.dll, handle 0x00007ffbfd960000
[0.053s][info][library] Failed to find _JNI_OnLoad@8 in library with handle 0x00007ffbfd960000
[0.053s][info][library] Failed to find JNI_OnLoad in library with handle 0x00007ffbfd960000
[0.054s][info][library] Found Java_jdk_internal_jimage_NativeImageBuffer_getNativeMap in library with handle 0x00007ffbfd960000
英文:
You can use the -Xlog:library=trace
VM flag to print out information about libraries that are loaded and symbol lookups. For instance:
> java '-Xlog:library=info' Main
[0.011s][info][library] Loaded library jsvml.dll, handle 0x00007ffbd4ab0000
[0.052s][info][library] Failed to find _JNI_OnLoad_jimage@8 in library with handle 0x00007ff6a9610000
[0.052s][info][library] Failed to find JNI_OnLoad_jimage in library with handle 0x00007ff6a9610000
[0.053s][info][library] Loaded library C:\Program Files\Java\jdk-17\bin\jimage.dll, handle 0x00007ffbfd960000
[0.053s][info][library] Failed to find _JNI_OnLoad@8 in library with handle 0x00007ffbfd960000
[0.053s][info][library] Failed to find JNI_OnLoad in library with handle 0x00007ffbfd960000
[0.054s][info][library] Found Java_jdk_internal_jimage_NativeImageBuffer_getNativeMap in library with handle 0x00007ffbfd960000
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论