jdk/bin工具是jvm诊断直接入口,需按问题反推使用:卡死用jstack查线程,内存问题用jmap看对象或dump,参数查询用jinfo,cpu高用jstat,注意权限、版本差异及jcmd替代方案。

JDK/bin 目录下的 .exe 工具不是“辅助程序”,而是 JVM 运行时诊断与开发的直接操作入口——它们不依赖 IDE,不走图形界面,命令敲错一个参数就可能查不到堆、连不上进程、甚至 dump 失败。
怎么快速识别哪个工具该用在什么场景
别背列表,按你正在面对的问题反推:
- Java 进程卡死、线程没响应?→ 优先跑
jstack <pid></pid>看线程栈,尤其注意WAITING或BLOCKED状态的线程是否成对出现(比如锁竞争) - 内存暴涨、GC 频繁、疑似泄漏?→ 先用
jmap -histo <pid></pid>快速看对象数量TOP10;真要分析就jmap -dump:format=b,file=heap.hprof <pid></pid>,再用jhat或 VisualVM 打开(注意:dump 会暂停应用几秒,生产慎用) - 想确认某个 JVM 参数当前值(比如
MaxHeapSize)?→jinfo -flag MaxHeapSize <pid></pid>,比翻启动脚本快得多 - 刚上线的应用 CPU 突然飙高?→
jstat -gc -h10 <pid> 1000 5</pid>(每秒打一次 GC 统计,共5次),观察YGC/FGC次数和耗时,别一上来就 jstack
jmap 和 jstack 的常见误用坑
这两个命令看着简单,但权限、时机、JDK 版本差异直接决定结果是否可信:
-
jstack在 Windows 上若没以管理员身份运行,可能报Unable to open socket file—— 不是进程挂了,是权限不够读/proc类路径(Windows 下对应的是共享内存区) -
jmap -dump对 JDK 8u261+ 默认要求目标进程启用-XX:+UseContainerSupport(容器环境)或显式加-XX:+UnlockDiagnosticVMOptions,否则直接拒绝执行 - 用
jmap -histo看到大量[C(char[])或[B(byte[])?别急着删代码——先确认是不是日志框架(如 Logback)的异步队列堆积,或是 HTTP body 缓存未释放 -
jstack输出里出现java.lang.Thread.State: RUNNABLE并不等于“正在干活”,它也可能卡在synchronized入口、IO 等待、甚至Unsafe.park(线程池空闲等待)
为什么有些工具在 JDK 17+ 里找不到了
不是删了,是拆了、移了、或换名了:
-
javah从 JDK 10 起彻底移除,JNI 头文件改用javac -h生成(例如:javac -h ./jni MyNativeClass.java) -
jhat自 JDK 9 起废弃,官方推荐用jvisualvm或 Eclipse MAT 分析.hprof文件;硬要用的话得单独下载旧版 JDK 8 的 bin 目录补上 -
appletviewer、javaws这类 Applet/Web Start 工具,在 JDK 11 中已删除——它们依赖的插件机制早已被主流浏览器弃用 -
jcmd是替代方案之一:它能做jmap、jstack、jinfo的大部分事,且无需额外 JVM 参数(比如:jcmd <pid> VM.native_memory summary</pid>查本机内存)
真正难的不是记住每个命令,而是看到 OutOfMemoryError: Metaspace 时,立刻想到该用 jstat -gcmetacapacity <pid></pid> 而不是 jmap -histo;或者发现线程数持续上涨,第一反应是 jstack 后 grep java.util.concurrent 而不是直接重启。这些判断背后,是工具行为和 JVM 内部机制的咬合点——漏掉一个,排查就绕三圈。










