1. JDK 命令行工具
- jps(查看 HotSpot 虚拟机进程) –> jstack(虚拟机进程中的线程快照)
- jinfo(虚拟机配置信息) –> jstat(HotSpot 运行时的数据)
- jmap(虚拟机内存快照 heapdump 文件) –> jhat(分析 heapdump 文件)
工具的实现都在 jdk/lib/tools.jar 类库
1.1. jps: 查看虚拟机进程
jsp (JVM process Status Tool),可以显示正在运行的 Java 进程,以及虚拟机执行的主类信息。
1.1.1. 命令格式
1 | [root@test ~]# jps -help |
hostid 可以不填写,例如:
1 | [root@test ~]# jps -mlv |
1.1.2. 常用参数
| 选项 | 作用 |
|---|---|
| -m | 输出虚拟机进程启动时传递给主类 main() 函数的参数 |
| -l | 输出主类饿全名,如果进程执行的是 jar 包,输出 jar包路径 |
| -v | 输出虚拟机进程启动时的 JVM 参数 |
1.2. jstack
jstack (Stack Trace for Java ) 用户生成当前时刻的虚拟机线程快照。往往在排查 Java 进程 CPU 飙高,线程卡死,线程数升高,线程运行卡顿,线程死锁等问题,非常有效。(曾经解决过一个线程数量飙升的问题,就是利用这个工具,查处了有许多相同的线程)。
1.2.1. 命令格式
1 | [root@test ~]# jstack -help |
1.2.2. 常用参数
| 选项 | 作用 |
|---|---|
| -F | 当正常输出的请求不被响应时,强制输出线程堆栈 |
| -l | 除堆栈外,显示关于锁的附加信息 |
| -m | 如果调用到本地方法的法(JNI), 可以显示 C/C++ 的堆栈 |
1.2.3. 获取虚拟机所有线程信息
JDK 1.5 中,java.lang.Thread.getAllStackTraces() 方法可以获取虚拟机栈中所有线程的 StackTraceElement 对象。使用这个方法可以通过几行简单的代码完成 jstack 大部分的功能。所以,可以做一个 html 页面,随时获取虚拟机堆栈的线程信息。
1.3. jinfo
Java 配置信息工具,可以实时的查看和调整虚拟机运行期可写的参数。
1.3.1. 命令格式
1 | [root@test ~]# jinfo -help |
1.3.2. 常用参数
| 选项 | 作用 |
|---|---|
| -flags | 显示 VM 虚拟机的运行参数 |
1.3.3. 修改虚拟机配置
1 | jinfo -flag name=value |
1.3.4. java -XX:+PrintFlagsFinal 使用
注意 : JDK 1.6 及以上版本
可以通过 grep 命令过滤自己需要查询的参数默认值。
1.3.4.1. 命令格式
1 | » java -XX:+PrintFlagsFinal -help #查看帮助文档 |
比如,查看虚拟机默认的的堆内存大小:
1 | » java -XX:+PrintFlagsFinal -version | grep -i HeapSize |
1.3.4.2. 物理内存和堆默认值的关系
物理内存 mem ,那么初始堆(InitialHeapSize)的大小 = mem * 1/64,最大值分两种情况:
- 0 < mem < 192MB : 堆最大为在物理内存 50%(1/2)
- 192MB < mem : 堆最大为在物理内存 25%(1/4)
我的电脑是 16G 内存,所以:
InitialHeapSize = 16/64 * 1024 * 1024 * 1024 = 268435456 = 256MB
MaxHeapSize = 16/4 * 1024 * 1024 * 1024 = 4294967296 = 4G
1.4. jstat
jstat 虚拟机统计信息监视工具,可以查看 JVM 当前各个区域的内存分配,GC 总次数和总耗费时长,而且可以定时刷新监控。
1.4.1. 命令格式
1 | 帮助 |
参数 interval 和 count 代表查询间隔和次数,如果省略这两个参数,表示只查询一次。假设,需要 250ms 查询一次进程 2764 的垃圾手机状况,一共查询 20 次,那命令应该是:
1 | jstat -gc 2764 250 20 |
1.4.2. 常用参数
| 选项 | 作用 |
|---|---|
| -class | 监视类装载、卸载数量、总空间以及类装载锁耗费的时间 |
| -gc | 监视 JVM 堆状况,包括 Eden 区,两个 survivor 区、老年代、永久带等的容量、已用空间,GC 时间合计信息 |
| -gccapacity | 监视内容和 -gc 基本相同,但是输出主要关注 Java 堆各个区域的使用到的最大、最小空间 |
| -gcutil | 监视内容和 -gc 基本相同,但是输出主要关注已使用空间占总空间的百分比 |
| -gccause | 与 -gcutil 功能一样,但是会额外输出导致上一次 GC 产生的原因 |
| -gcmetacapacity | 输出 Meta Space 使用到的最大最小空间,以及 GC 情况 |
| -gcnew | 监视新生代 GC 状况 |
| -gcnewcapacity | 与 -gcnew 基本相同,输出主要是关注使用到的最大、最小空间 |
| -gcold | 监视老年代 GC 状况 |
| -gcoldcapacity | 与 -gcold 基本相同,输出主要是关注使用到的最大、最小空间 |
| -compiler | 输出 JIT 编译器编译过的方法,耗时等信息 |
| -printcompilation | 输出已经被 JIT 编译的方法 |
1.5. jmap
jmap(Memory Map for Java),Java 内存映像工具,用户堆快照生成,也就是我们说的 heapdump 文件。
1.5.1. 除开 jmap 获取 heapdump 文件的方式
1.5.1.1. -XX:+HeapDumpOnOutOfMemoryError 参数
如果不使用 jmap 命令,可以通过设置 -XX:+HeapDumpOnOutOfMemoryError 参数,在虚拟机出现 OOM 异常后自动生成 dump 文件。
1.5.1.2. -XX:+HeapDumpOnCtrlBreak 参数
该方式只能适用于 JDK 1.4.2_12 或者更高一级 1.5.0_14 或者更高。
JDK 1.6, 1.7, 1.8 已经移除了这种方式。
1.5.1.3. kill -3(还没找到生成的文件位置??)
Linux 系统下可以通过 kill -3 命令发送给 Java 进程退出信号“吓唬”一下虚拟机,也能拿到 dump 文件。
生成的 dump 文件目录在:
When ‘kill -3’ option is used thread dump is sent to the standard error stream. If you are running your application in tomcat, thread dump will be sent into
/logs/catalina.out file.
1.6.
1.6.1. 命令格式
1 | » jmap -help |
1.6.2. 常用参数
| 选项 | 作用 |
|---|---|
| -dump | 生成 Java 堆转储快。格式为:-dump:[live,]format=b,file= |
| -finalizerinfo | 显示在 F-Queue 中等待 Finalizer 线程执行 finalize 方法的对象,只在 *ix 平台有效 |
| -heap | 显示 Java 堆详细信息,如使用哪种回收期、参数配置、分代状况等,只在 *ix 平台有效 |
| -histo | 显示对象统计信息,包括类、实例数量、合计容量 |
| -F | 如果 -dump 没有响应,使用 -F 强制生成 dump 快照 |
1.7. jhat
jhat(JVM Heap Analysis Tool),虚拟机转存快照分析工具,与 jmap 搭配使用。但是这个命令不常用,原因两个:
- 命令行工具限制太多
- 分析功能相对比较简陋
常用做法是把 dump 文件下载到本地,使用 Visual VM 或者 Eclipse Memory Analyzer 等工具来分析。
1.8. HSDIS
HSDIS 是一个 Sun 官方推荐的 HotSpot 虚拟机 JIT 编译代码的反汇编插件,包含在 HotSpot 虚拟机的源码种植,但是没有提供编译后的程序。