当前位置: 首页 > news >正文

JVM常用工具:jstat、jmap、jstack

内存溢出

小结

jps找出进程号,jmap转储heap文件,jhat分析堆文件。抑或可以jvisual等直接监控分析堆。

模拟代码

// 内存泄漏示例:静态集合持有对象,无法被 GC 回收
public class OutMemoryDemo {// 静态集合:生命周期与 JVM 一致,对象无法被回收private static final List<byte[]> LEAK_LIST = new ArrayList<>();public static void main(String[] args) throws InterruptedException {System.out.println("开始内存泄漏...");int count = 0;while (true) {// 每次分配 1MB 内存(byte[1024 * 1024])LEAK_LIST.add(new byte[1024 * 1024]);count++;// 每 100 次打印一次内存占用if (count % 100 == 0) {System.out.printf("已分配 %d 个对象,总占用约 %d MB%n",count, count * 1);}// 短暂休眠,减缓内存增长速度(方便观察)Thread.sleep(50);}}
}

转储堆文件

jmap -dump:live,format=b,file=F:/Temp/heap_dump.hprof  28204

在这里插入图片描述

分析堆文件

jhat F:/Temp/heap_dump.hprof

由于1.8的bin下有jhat:访问localhost:7000

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

PS:这里的class[B指的是Java的基础变量byte,对应的C是char,这个大家自然不陌生可以推断出其他的变量。

垃圾回收

Jstat

jstat(Java Virtual Machine Statistics Monitoring Tool) 是 JDK 自带的命令行工具,用于监控 JVM 运行时状态,包括类加载、GC、堆内存、编译等统计信息。

在IDEAL中的VM OPTIONS中加入(Run Configure):

-Xms64m -Xmx64m -XX:+PrintGCDetails JstatDemo

测试代码

事实上,可以采用直接设置List对象进行反复加入和清空来模拟取代设置堆内存大小启动参数和GC日志打印

public class JstatDemo {public static void main(String[] args) throws InterruptedException {System.out.println("开始测试 jstat...");int count=0;// 无限循环分配小对象(触发 GC)while (true) {// 分配 1MB 内存(byte 数组)byte[] data = new byte[5 * 1024 * 1024];// byte[] data = new byte[100 * 1024];System.out.println("已经分配内存:" + ++count + "0MB");// System.out.println("已经分配内存:" + ++count + "00KB");// 短暂休眠(让 jstat 能捕捉到内存变化)Thread.sleep(2000);}}
}

在这里插入图片描述

分析GC

jstat [option] pid [interval] [count]

jstat -gcutil 26072 1000 3

在这里插入图片描述

为什么是Old区呢,因为对象太大,将分配对象修改为100KB

在这里插入图片描述

补充参数常用选项:

OPTIONS

选项说明
-class监控类加载/卸载数量及耗时(Loaded/Unloaded/Time)。
-compiler显示 JIT 编译器编译的方法数量及耗时。
-gc堆内存各区域容量(Capacity)及实际使用量(Usage),包含 GC 次数/时间。
-gccapacity堆内存各区域的容量(最小/最大/当前)。
-gcutil以百分比显示堆内存使用率,并输出 GC 统计。
-gccause-gcutil,额外显示最近一次和当前 GC 的原因(如 Allocation Failure)。
-gcnew新生代(Young Gen)内存统计。
-gcold老年代(Old Gen)内存统计。
-gcmetacapacity元空间(Metaspace)容量统计(JDK8+)。
-gc 输出字段
字段含义示例
S0CSurvivor 0 区容量(KB)10240.0
S1CSurvivor 1 区容量10240.0
S0USurvivor 0 区已使用量0.0
S1USurvivor 1 区已使用量1024.0
ECEden 区容量81920.0
EUEden 区已使用量40960.0
OC老年代容量204800.0
OU老年代已使用量102400.0
YGCYoung GC 次数100
YGCTYoung GC 总耗时(秒)5.456
FGCFull GC 次数3
FGCTFull GC 总耗时1.234
GCTGC 总耗时6.690
-gcutil 输出字段(百分比形式)
字段含义示例
S0Survivor 0 区使用率50.00
S1Survivor 1 区使用率0.00
EEden 区使用率75.25
O老年代使用率85.30
M元空间(Metaspace)使用率95.80
CCS压缩类空间(Compressed Class Space)使用率80.50
YGCYoung GC 次数200
YGCTYoung GC 总耗时10.20
FGCFull GC 次数5
FGCTFull GC 总耗时3.50
GCT总 GC 耗时13.70

Jinfo

jinfo对应进程PID:

jinfo [pid]

注意:使用jdk指令的时候,往往要注意对应java程序的版本尽可能的保持一致,否则可能出现:

Error attaching to process: Windbg Error: GetModuleParameters failed!

我这里采用1.8的jinfo分析jdk17运行程序的进程pid出现如上报错

在这里插入图片描述

可视化监控Jconsole/Jvisualvm

一般可视化的集成了常用的指令(但是服务器和环境不一定会让我们使用或连接得上,工作多年的同志们可以理解),方便展示图形(相对于堆的64MB),修改分配内存为5MB:

在这里插入图片描述

死锁

这一块儿包括上面,其实21年就已经有记录,不过没有总结归纳(就像有很多存货和系列其实没发布整理),就不重新再跑和复现了(可视化对应的应该是jvisualvm):

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

jstack -heap pid

在这里插入图片描述

http://www.lryc.cn/news/624092.html

相关文章:

  • Transformer架构的数学本质:从注意力机制到大模型时代的技术内核
  • 因果语义知识图谱如何革新文本预处理
  • 机器学习案例——对好评和差评进行预测
  • Python开发环境
  • 说一下事件传播机制
  • Pandas数据结构详解Series与DataFrame
  • 【C#补全计划】多线程
  • 《解构WebSocket断网重连:指数退避算法的前端工业级实践指南》
  • 代码随想录刷题——字符串篇(五)
  • MySQL数据库初识
  • Linux 服务:iSCSI 存储服务配置全流程指南
  • 「数据获取」《中国文化文物与旅游统计年鉴》(1996-2024)(获取方式看绑定的资源)
  • ICCV 2025 | Reverse Convolution and Its Applications to Image Restoration
  • 一键管理 StarRocks:简化集群的启动、停止与状态查看
  • HTTP请求方法:GET与POST的深度解析
  • 【技术博客】480p 老番 → 8K 壁纸:APISR × SUPIR × CCSR「多重高清放大」完全指南
  • PCA 实现多向量压缩:首个主成分的深层意义
  • 平行双目视觉-动手学计算机视觉18
  • Go语言并发编程 ------ 锁机制详解
  • C++析构函数和线程退出1
  • C++继承(2)
  • Eclipse Tomcat Configuration
  • Docker-14.项目部署-DockerCompose
  • Docker入门:容器化技术的第一堂课
  • 飞算JavaAI赋能高吞吐服务器模拟:从0到百万级QPS的“流量洪峰”征服之旅
  • Linux软件编程:进程与线程(线程)
  • ruoyi-vue(十一)——代码生成
  • 最长回文子串问题:Go语言实现及复杂度分析
  • vulnhub-lampiao靶机渗透
  • 科目二的四个电路