jps, jmap, jhat, mat, jstat

本文详细介绍了Java内存分析工具jps、jmap、jhat和MAT的使用方法,包括如何查看Java进程、分析内存占用、查找内存泄漏等问题,并提供了jstat工具的高级用法。

jps:

与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号。

jps -mlv

可查看java进程的全路径名

jmap:

jmap(java memory map)是用来对正在运行的java进程进行内存、对象分析的。通过jmap可以获得进程中不同类的实例数量,并可以dump出当前进程状态,供分析使用(使用jhat,MAT等分析工具)。

常用参数:

jmap -histo[:live] ${pid}

打印某pid中,不同类的实例数量和占用空间,默认按占用空间排序。如果使用了:live选项,仅获取生存的对象,但是会导致gc。
tips:
由于Spring中ioc自动扫描的bean,默认都是单例。如果某个Service出现两个bean,会导致一些问题,常见的是null pointer等。通过日志可以确认有没有类的覆盖(override),通过jmap定位到该类,确认是否有多个实例被创建。
注:
jmap -histo,如果加了:live会导致程序进入gc,stop-the-world。

jmap -dump:[live,]format=b,file=${XXXDump.bin} ${pid}

将某pid的内存镜像dump下来,存为${XXXDump.bin}文件,用于结合jhat,MAT分析。
tips:
获取内存镜像可以做很多工作,比如用jhat获得不同类的所有实例个数,每个实例的内部变量值等等。
注:

  1. jmap -dump这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用。
  2. 如果想dump堆信息,可以使用gcore命令,比jmap -dump快。
jmap -heap ${pid}

-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况。通常用来排查jvm的问题(如gc次数、时间异常等,配合jstat -gcutils排查)
###经典场景:

  1. 内存泄漏memory leak,通过jmap -histo获取类的实例数量,判断是否有问题。
  2. 发现有本应是单例的结果重复加载(日志中的override、莫名的nullpointer等),通过jmap -dump获取内存镜像,用jhat和MAT分析。
    用jhat ${pid}可以解析镜像文件到域名(默认本机7000),直接用浏览器访问也可以得到类和实例的状态。有MAT可以分析得更可视化。

jhat:

jhat命令解析会Java堆dump并启动一个web服务器,默认7000端口,可以在浏览器中查看堆的dump文件,获得dump文件中的对象数量及状态。常与jmap命令合作,使用jmap -dump:format=b,file=a.bin ${pid}获取dump文件后,使用jhat进行分析。个人认为jhat的功能是MAT功能的子集。
常用功能有

  1. Show instance counts for all classes (excluding platform),平台外的所有对象信息。
    以及
  2. Show heap histogram 以树状图形式展示堆情况。
    树状图的输出很像jmap -histo的结果,用法也类似。
    此命令的常用方式是分析dump文件,可以用浏览器轻松获取某个类的实例对象,是否被加载了等等。

mat:

http://blog.youkuaiyun.com/itomge/article/details/48719527
http://www.lightskystreet.com/2015/09/01/mat_usage/
http://blog.youkuaiyun.com/xx326664162/article/details/50084543

jstat:

jstat也是jdk提供的对jvm监控的工具之一,使用方法网上文章较多。如http://blog.youkuaiyun.com/fenglibing/article/details/6411951。笔者常用的选项包括:
jstat -gcutil {pid} {timeinterval} :可以指定时间间隔打印jvm的各部分空间占用,以及gc数据。
jstat -gccause {pid} :可以获取gc的原因
jstat -class {pid} :可以打印jvm的类加载信息,如加载类的数量,占用空间,加载类的耗时等。

tip1: jstat为什么只有ygc和fgc,没有major gc的信息?

此处提出一点笔者的积累。jvm的minor gc概念清晰(回收young gen),但是major gc和full gc的概念较为模糊,详情可见http://blog.youkuaiyun.com/ligeforrent/article/details/76619057中R大在知乎的回答。 这种模糊在jstat中也有所体现。
在jstat中关于gc的指标只有ygc和fgc,没有major gc的数据。这一度让笔者感到不解,直到看到了一篇译文(http://blog.youkuaiyun.com/ligeforrent/article/details/76619057)。其中明确地指出,其实jstat中的fgc不能真正表示full gc,它是指:发生old gen清理时,stop-the-world的次数和时间。
由于CMS中存在独立的major gc(CMS GC) 和 full gc,当发生CMS GC时,会发生初始标记-并发标记-重新标记-并发清理。其中1,3是STW的,会在jstat中体现为两次fgc。其实在CMS GC工作正常时,是不需要发生真正的serial full gc的。这种情况只能在GC日志中看出,通过jstat是看不出的。
如果把jstat中的fgc理解为stop-the-world,它的输出结果也是正确的,一次CMS GC确实会发生两次较短的stw(相较于serial full gc较短)。

<think>我们正在回答用户关于jstatjmap工具的使用方法的问题。根据用户的要求,我们需要参考之前提供的引用内容,并结合用户上一次的问题(关于jps的使用)来构建回答。 引用内容中与jstatjmap相关的部分: 引用[1]:提到jstat/jmap/jstack是OOM问题排查的关键工具,并提到“掌握内存泄漏定位三板斧”。 引用[3]:标题就是关于jps、jstack、jmapjhatjstat等工具的使用详解,其中提到jstack定位线程堆栈,jmap用于内存分析。 引用[4]:详细介绍了JVM工具的组合使用,包括jmap、jstack、jstat,并给出了具体的使用场景注意事项。 回答结构: 1. 前置条件:确保环境变量配置正确,有权限执行这些命令。 2. jstat工具:用于监控JVM的各种统计信息,特别是垃圾回收类加载信息。 3. jmap工具:用于生成堆转储快照(heap dump)查看堆内存的详细信息。 4. 典型使用场景:结合引用[4]中的工具组合建议,给出实际案例。 5. 常见问题:如权限问题、容器内使用问题等。 6. 与其他工具联动:如结合MAT分析堆转储文件,结合jps获取进程ID。 由于用户之前问了jps,我们可以先强调jps用于获取进程ID,然后jstatjmap都需要使用这个进程ID。 注意:回答中需要自然地添加引用标识,例如在引用到引用[4]的地方标注[^4]。</think>### Java jstat jmap 使用指南 `jstat` `jmap` 是 JDK 自带的 JVM 性能诊断工具,用于监控内存、GC 状态及生成堆转储文件。以下是详细使用方法: --- #### **1. 前置条件** - **安装 JDK**:确保 `$JAVA_HOME/bin` 已加入 PATH - **获取目标进程 PID**:先用 `jps -l` 获取 Java 进程 ID ```bash $ jps -l 5678 com.example.MyApp # 目标进程 PID=5678 ``` --- #### **2. jstat:实时 JVM 统计监控** **核心功能**:监控堆内存、GC 活动、类加载等实时数据[^3][^4]。 | 命令格式 | 作用 | 关键输出项解析 | |----------|------|----------------| | `jstat -gc <PID> <间隔ms> <次数>` | 监控 GC 行为 | `S0C/S1C`:Survivor 区容量<br>`EU`:Eden 使用量<br>`OU`:老年代使用量<br>`YGC/YGCT`:Young GC 次数/耗时<br>`FGC/FGCT`:Full GC 次数/耗时 | | `jstat -gccapacity <PID>` | 内存池容量 | `NGCMN/NGCMX`:新生代最小/最大容量<br>`OGCMN/OGCMX`:老年代最小/最大容量 | | `jstat -class <PID>` | 类加载统计 | `Loaded`:已加载类数<br>`Bytes`:加载的字节数<br>`Unloaded`:已卸载类数 | **典型场景**: ```bash # 每 2 秒输出 1 次 GC 状态,共 5 次 $ jstat -gc 5678 2000 5 # 输出示例 S0C S1C S0U S1U EC EU OC OU MC YGC YGCT FGC FGCT 1024.0 1024.0 0.0 1024.0 8192.0 8192.0 20480.0 10240.0 4864.0 10 0.250 2 0.500 ``` > **分析重点**:若 `FGC` 持续增加且 `OU`(老年代使用量)接近 `OC`(老年代容量),可能存在内存泄漏或 GC 策略不当[^4]。 --- #### **3. jmap:堆内存分析与转储** **核心功能**:生成堆转储快照(heap dump)、查看堆内存分布[^3][^4]。 | 命令 | 作用 | 注意事项 | |------|------|----------| | `jmap -heap <PID>` | 显示堆内存配置 | 输出 Eden/Survivor/老年代大小及 GC 算法 | | `jmap -histo <PID>` | 显示对象直方图 | 按实例数量排序:`num #instances #bytes class name` | | `jmap -dump:format=b,file=heap.hprof <PID>` | 生成堆转储文件 | 生产环境慎用!可能暂停应用且文件较大(建议挂载 Volume 导出) | **典型场景**: ```bash # 1. 查看堆内存分布(快速定位大对象) $ jmap -histo 5678 | head -20 # 显示前20行 # 输出示例 num instances bytes class name ----------------------------------------- 1: 100000 2000000 [B # byte数组 2: 50000 1500000 java.lang.String # 2. 生成堆转储文件并用 MAT 分析 $ jmap -dump:live,format=b,file=myapp_heap.hprof 5678 ``` > **最佳实践**: > - 内存泄漏分析:`jmap -dump` + MAT 工具(定位持有对象的 GC Root) > - 容器环境:通过 `docker exec` 在容器内执行或挂载 Volume 导出文件[^4] --- #### **4. 工具组合实战案例** **场景:内存泄漏排查** 1. **监控 GC**:`jstat -gc 5678 1000` → 发现 `FGC` 持续增加且 `OU` 不降 2. **对象分析**:`jmap -histo 5678` → 发现某类实例数异常增长 3. **生成堆转储**:`jmap -dump:file=leak.hprof 5678` 4. **MAT 分析**:导入 `leak.hprof`,查找 Dominator Tree 定位泄漏对象[^1][^4] **场景:CPU 飙高分析** 1. `top -Hp 5678` → 定位高 CPU 线程 ID(如 5890) 2. 转换线程 ID:`printf "%x\n" 5890` → 得到 16 进制值 `1702` 3. `jstack 5678 | grep -A 20 1702` → 查看该线程堆栈[^3][^5] --- #### **5. 注意事项与替代方案** | 问题 | 解决方案 | 替代工具 | |------|----------|----------| | 容器内权限不足 | `docker exec -it <容器> jmap ...` | Arthas(无侵入式诊断)[^4] | | `jmap` 导致服务暂停 | 使用 `-live` 参数减少影响 | 在低峰期操作 + 预留内存 | | 堆文件过大 | 压缩传输:`gzip heap.hprof` | 使用轻量级 `jcmd GC.heap_dump` | | 无法连接 JVM | 检查 `-XX:+DisableAttachMechanism` 配置 | 通过 K8s 探针获取数据[^1] | > **安全提示**:生产环境使用 `jmap` 前务必评估影响,建议通过 JMX 远程连接诊断[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值