You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JDK 17应用中识别通过JNI调用的本地库?

在JDK 17中识别JNI调用的本地库方法

已确认Java应用存在原生代码内存泄漏,且问题不在应用自身Java代码中,需要排查依赖的本地库。早期依赖反射访问ClassLoader.loadedLibraryNames的方式在JDK 17中已失效,以下是JDK 17可用的合规方案:

1. 使用Runtime类的loadedLibraries()方法(JDK 9+)

JDK 9引入了Runtime.loadedLibraries()方法,可直接获取所有已加载的本地库路径,无需反射,完全符合JDK模块化规范。代码示例:

import java.lang.Runtime;

public class NativeLibChecker {
    public static void main(String[] args) {
        Runtime.getRuntime().loadedLibraries().forEach(System.out::println);
    }
}

执行后会输出所有已加载本地库的绝对路径,方便定位可疑依赖。

2. 通过JVM启动参数打印加载详情

启动应用时添加以下参数之一,JVM会在控制台输出本地库的加载信息:

  • XX:+PrintLibraryLoadingDetails:输出详细的库加载日志,包括加载的路径、时间及关联类
  • -XX:+PrintSharedSpaces:输出共享库(包括本地库)的加载情况
    无需修改代码,适合快速排查场景。

3. 使用JDK工具jcmd离线排查

通过jps命令获取应用进程ID后,执行以下命令:

jcmd <你的应用PID> VM.native_libraries

该命令会输出进程中所有已加载本地库的详细信息,包括库路径、加载状态、内存映射地址等,是生产环境离线排查的常用手段。

4. 自定义ClassLoader追踪加载行为

如果应用使用自定义ClassLoader加载本地库,可以重写findLibrary方法来记录加载的库信息:

public class TrackingClassLoader extends ClassLoader {
    @Override
    protected String findLibrary(String libname) {
        String libPath = super.findLibrary(libname);
        if (libPath != null) {
            System.out.printf("ClassLoader加载本地库:%s,路径:%s%n", libname, libPath);
        }
        return libPath;
    }
}

这种方式适合追踪特定ClassLoader加载的本地库,需要结合应用的类加载逻辑使用。

内容的提问来源于stack exchange,提问作者Augustin Cayot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:48:18