JVM内存分析
发布于2025-08-10 01:13:14,更新于2025-08-10 16:44:31,标签:java 文章会持续修订,转载请注明来源地址:https://meethigher.top/blog简单记录JVM内存分析的步骤。之前有过相关的调优,参考
其实我在这块的经验也少之又少,毕竟没遇到过类似极端调优的情况。不过还是觉得有必要记录下排查的步骤
- 第一步,查GC
- 第二步,查导致GC的罪魁祸首,即对象实例
- 第三步,按需调整JVM堆内存
一、查GC
命令。每5秒输出pid对应进程的gc情况。
1 | jstat -gc pid 5s |
输出内容格式如下
1 | S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT CGC CGCT GCT |
参数含义如下
jstat参数 | 内存区域对应 | 说明(大小单位为KB、时间单位为秒) |
---|---|---|
S0C, S1C | Survivor区容量 | Survivors容量 |
S0U, S1U | Survivor区使用量 | 当前使用量 |
EC, EU | Eden区容量和使用量 | 新对象分配区 |
OC, OU | 老年代容量和使用量 | 长寿命对象区 |
MC, MU | 元空间容量和使用量 | 存放类的元数据(类定义、方法、常量池等),使用Native内存,通过 -XX:MaxMetaspaceSize 参数设置,默认不限制 |
YGC, YGCT | Minor GC次数和耗时 | 年轻代GC,清理Eden |
FGC, FGCT | Full GC次数和耗时 | 完全GC,清理老年代 |
CGC,CGCT | CGC次数和耗时 | 并发GC |
GCT | GC总耗时 | 包括年轻代GC、完全GC及并发GC的总耗时 |
GC的执行流程如下
不管是Minor GC还是Full GC,都会在GC期间出现STW(Stop The World)现象。
二、查对象实例
查询对象的实例,定位是哪边的逻辑导致频繁创建对象。查询期间会造成STW。
1 | # 只统计存活对象的数量和大小,输出文本报告 |
其中使用到MAT分析,可以精确的定位到是哪边的代码创建的对象实例过多。下载地址Downloads | The Eclipse Foundation
三、调整JVM堆内存
JVM内存,分为堆内存和非堆内存。结构组成如下
常用参数如下
参数 | 作用 | 示例 | 说明 |
---|---|---|---|
-Xms | 初始堆大小,默认为物理内存大小的1/64 | -Xms512m | JVM 启动时就分配的堆大小,建议与 -Xmx 相等以避免运行时动态扩容带来的抖动。 |
-Xmx | 最大堆大小,默认为物理内存大小的1/4 | -Xmx2g | 堆能增长到的最大值,超过会抛 OutOfMemoryError: Java heap space 。 |
-Xmn | 年轻代大小,默认为物理内存大小的1/8 | -Xmn512m | 包括 Eden + Survivor,较大可以减少 Minor GC 次数,但会压缩老年代空间。 |
-XX:NewRatio | 年轻代与老年代的比例,默认为2 | -XX:NewRatio=2 | 表示老年代 : 年轻代 = 2 : 1,不直接设置 -Xmn 时生效。 |
-XX:SurvivorRatio | Eden 与单个 Survivor 区比例,默认为8 | -XX:SurvivorRatio=8 | 默认 8:1:1,Eden 占年轻代 80%,每个 Survivor 占 10%。 |
JVM调整思路如下
- 定堆大小:
-Xms
和-Xmx
设置成一样,避免动态扩容 - 监控再调整:若短命对象多,则增大年轻代;若长命对象多,则增大老年代
打赏