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

如何从外部查询已知PID的运行中JVM已加载的命名JPMS模块?

查询运行中JVM已加载的命名JPMS模块的简洁方法

当然有更省心的方法!不用费劲去解析jcmd <pid> VM.class_hierarchy的冗长输出,Java 9+早就为JPMS模块查询提供了更直接的工具和方案:

1. 最推荐:用jcmd的VM.module命令

这是官方专门为模块信息查询设计的命令,简单到一步到位。在终端直接运行:

jcmd <pid> VM.module

它会输出所有已加载模块的规整信息,包括:

  • 命名模块的名称、版本、模块路径、加载状态
  • 明确标记的unnamed module(你提到的未命名模块)
    完全不需要自己做复杂的文本解析,一眼就能区分出所有命名JPMS模块。

2. 可视化选择:使用JConsole

如果你偏好图形化界面,JConsole能直观展示模块列表:

  • 启动jconsole,在连接窗口选择目标PID对应的JVM实例
  • 连接成功后切换到Modules标签页,就能看到所有已加载模块的分类列表,命名模块和未命名模块清晰区分,还能查看每个模块的依赖、导出包等细节

3. 自动化场景:用Attach API编写工具

如果需要批量或自动化查询,可以借助Java Attach API写一个轻量工具。核心逻辑是附加到目标JVM后,通过模块API获取命名模块:

import com.sun.tools.attach.VirtualMachine;
import java.lang.module.ModuleDescriptor;
import java.util.Set;
import java.util.stream.Collectors;

public class NamedModuleLister {
    public static void main(String[] args) throws Exception {
        if (args.length == 0) {
            System.out.println("请传入目标JVM的PID");
            return;
        }
        String pid = args[0];
        VirtualMachine vm = VirtualMachine.attach(pid);
        try {
            // 获取启动层中的所有命名模块
            Set<Module> namedModules = ModuleLayer.boot().modules().stream()
                    .filter(Module::isNamed)
                    .collect(Collectors.toSet());
            
            namedModules.forEach(module -> {
                ModuleDescriptor desc = module.getDescriptor();
                System.out.printf("模块名: %s,版本: %s%n", 
                    desc.name(), 
                    desc.version().orElse("无版本信息"));
            });
        } finally {
            vm.detach();
        }
    }
}

注意:运行这个工具需要依赖JDK的相关模块(如jdk.attach),且需要足够的系统权限来附加到目标JVM。

总结

日常临时查询优先用jcmd <pid> VM.module,简洁高效零额外工作;可视化需求选JConsole;自动化或批量场景可以基于Attach API封装工具。

内容的提问来源于stack exchange,提问作者Hamid Nazari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:18:30