当前位置: 首页 > 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.xdnf.cn/news/1315945.html

相关文章:

  • 【Linux】IO多路复用
  • 17-线程
  • Python自学10-常用数据结构之字符串
  • Python异常、模块与包(五分钟小白从入门)
  • 文件快速复制工具,传输速度提升10倍
  • riscv中断处理软硬件流程总结
  • 【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day6
  • Vue3 中的 ref、模板引用和 defineExpose 详解
  • 安卓14系统应用收不到开机广播
  • 【Java后端】Spring Boot 集成 MyBatis-Plus 全攻略
  • 大模型算法岗面试准备经验分享
  • (机器学习)监督学习 vs 非监督学习
  • 智能制造——解读37页 案例分享灯塔工厂解决方案【附全文阅读】
  • 电子电气架构 --- 自动驾驶汽车的下一步发展是什么?
  • LeetCode 分类刷题:2962. 统计最大元素出现至少 K 次的子数组
  • 零墨云A4mini打印机设置电脑通过局域网络进行打印
  • 详解flink java基础(一)
  • Flink作业执行的第一步:DataFlow graph的构建
  • nodejs 错误处理
  • Gradle快速入门学习
  • 数据结构初阶(19)外排序·文件归并排序的实现
  • 机器学习案例——对好评和差评进行预测
  • error #include<cuda_runtime_api.h>解决方案
  • Java基础 8.17
  • 2023年全国研究生数学建模竞赛华为杯F题强对流降水临近预报求解全过程文档及程序
  • RAG 分块中表格填补简明示例:Markdown、HTML、Excel、Doc
  • 机器学习--数据清洗
  • 北京JAVA基础面试30天打卡12
  • STM32CUBEMX配置stm32工程
  • 五、redis入门 之 客户端连接redis