言成言成啊 | Kit Chen's Blog

JVM内存分析

发布于2025-08-10 01:13:14,更新于2025-08-10 16:44:31,标签:java  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

简单记录JVM内存分析的步骤。之前有过相关的调优,参考

其实我在这块的经验也少之又少,毕竟没遇到过类似极端调优的情况。不过还是觉得有必要记录下排查的步骤

  1. 第一步,查GC
  2. 第二步,查导致GC的罪魁祸首,即对象实例
  3. 第三步,按需调整JVM堆内存

一、查GC

命令。每5秒输出pid对应进程的gc情况。

1
jstat -gc pid 5s

输出内容格式如下

1
2
S0C         S1C         S0U         S1U          EC           EU           OC           OU          MC         MU       CCSC      CCSU     YGC     YGCT     FGC    FGCT     CGC    CGCT       GCT
512.0 512.0 403.5 0.0 21504.0 11004.3 59392.0 47119.4 71244.0 67123.0 9036.0 8418.4 1234 5.757 5 0.643 - - 6.401

参数含义如下

jstat参数内存区域对应说明(大小单位为KB、时间单位为秒)
S0C, S1CSurvivor区容量Survivors容量
S0U, S1USurvivor区使用量当前使用量
EC, EUEden区容量和使用量新对象分配区
OC, OU老年代容量和使用量长寿命对象区
MC, MU元空间容量和使用量存放类的元数据(类定义、方法、常量池等),使用Native内存,通过 -XX:MaxMetaspaceSize 参数设置,默认不限制
YGC, YGCTMinor GC次数和耗时年轻代GC,清理Eden
FGC, FGCTFull GC次数和耗时完全GC,清理老年代
CGC,CGCTCGC次数和耗时并发GC
GCTGC总耗时包括年轻代GC、完全GC及并发GC的总耗时

GC的执行流程如下

不管是Minor GC还是Full GC,都会在GC期间出现STW(Stop The World)现象。

二、查对象实例

查询对象的实例,定位是哪边的逻辑导致频繁创建对象。查询期间会造成STW。

1
2
3
4
5
# 只统计存活对象的数量和大小,输出文本报告
jmap -histo:live pid

# 把存活对象完整地拷贝到二进制heap dump文件里。供MAT离线分析
jmap -dump:live,format=b,file=dump.bin pid

其中使用到MAT分析,可以精确的定位到是哪边的代码创建的对象实例过多。下载地址Downloads | The Eclipse Foundation

三、调整JVM堆内存

JVM内存,分为堆内存和非堆内存。结构组成如下

常用参数如下

参数作用示例说明
-Xms初始堆大小,默认为物理内存大小的1/64-Xms512mJVM 启动时就分配的堆大小,建议与 -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:SurvivorRatioEden 与单个 Survivor 区比例,默认为8-XX:SurvivorRatio=8默认 8:1:1,Eden 占年轻代 80%,每个 Survivor 占 10%。

JVM调整思路如下

  1. 定堆大小:-Xms-Xmx设置成一样,避免动态扩容
  2. 监控再调整:若短命对象多,则增大年轻代;若长命对象多,则增大老年代
发布:2025-08-10 01:13:14
修改:2025-08-10 16:44:31
链接:https://meethigher.top/blog/2025/jvm-mem/
标签:java 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏