程序刚启动,发生三次FullGc的问题追踪

简介: 程序刚启动,发生三次FullGc的问题追踪,原因定位到JVM的默认参数Metaspace初始值和最大值是需要设置

问题现象

fe55baf9-d4d3-4765-a805-689b867b2386.png

从截图可以看出,程序刚启动发生了3次FullGc, 13次YGC

开启打印GC日志的命令

-XX:+PrintGCDetails -XX:+PrintGCTimeStamps

GC详细日志如下
[GC (Allocation Failure) [PSYoungGen: 65536K->6408K(76288K)] 65536K->6416K(251392K), 0.0148227 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
[GC (Allocation Failure) [PSYoungGen: 71944K->10063K(76288K)] 71952K->10151K(251392K), 0.0088836 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC (Metadata GC Threshold) [PSYoungGen: 41843K->7930K(76288K)] 41931K->8026K(251392K), 0.0055550 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] 
[Full GC (Metadata GC Threshold) [PSYoungGen: 7930K->0K(76288K)] [ParOldGen: 96K->7795K(89088K)] 8026K->7795K(165376K), [Metaspace: 20582K->20568K(1067008K)], 0.0237734 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] 
[GC (Allocation Failure) [PSYoungGen: 65536K->4667K(120320K)] 73331K->12471K(209408K), 0.0032643 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 119867K->10564K(136192K)] 127671K->18375K(225280K), 0.0078389 secs] [Times: user=0.03 sys=0.03, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 136004K->12791K(207872K)] 143815K->21645K(296960K), 0.0098903 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[GC (Metadata GC Threshold) [PSYoungGen: 173010K->15352K(210432K)] 181864K->24278K(299520K), 0.0093598 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[Full GC (Metadata GC Threshold) [PSYoungGen: 15352K->0K(210432K)] [ParOldGen: 8926K->20725K(139264K)] 24278K->20725K(349696K), [Metaspace: 34021K->34007K(1079296K)], 0.0524986 secs] [Times: user=0.09 sys=0.00, real=0.05 secs]
[GC (Allocation Failure) [PSYoungGen: 195072K->11399K(306688K)] 215797K->32133K(445952K), 0.0121779 secs] [Times: user=0.02 sys=0.00, real=0.01 secs].
[GC (Allocation Failure) [PSYoungGen: 306311K->17380K(342016K)] 327045K->51832K(481280K), 0.0195859 secs] [Times: user=0.06 sys=0.00, real=0.02 secs]
[GC (Metadata GC Threshold) [PSYoungGen: 137137K->25060K(401408K)] 171589K->61916K(540672K), 0.0181306 secs] [Times: user=0.03 sys=0.03, real=0.02 secs] 
[Full GC (Metadata GC Threshold) [PSYoungGen: 25060K->0K(401408K)] [ParOldGen: 36855K->45564K(206848K)] 61916K->45564K(608256K), [Metaspace: 56321K->56281K(1099776K)], 0.1520313 secs] [Times: user=0.39 sys=0.00, real=0.15 secs]
[GC (Allocation Failure) [PSYoungGen: 400103K->16619K(488960K)] 445675K->62199K(695808K), 0.0124262 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 484587K->30713K(498688K)] 530167K->82583K(705536K), 0.0273914 secs] [Times: user=0.06 sys=0.00, real=0.03 secs]

问题分析

从日志来看,FullGC三次都发生在 Full GC (Metadata GC Threshold)

old区离最大配置还很远,Metaspace区并没有真正释放空间,所以怀疑是Metaspace区不够用了

使用  java -XX:+PrintFlagsFinal -version 查看默认参数值为 21 MB,最大值为4096M = 4G

0bf6d127-25fc-450d-85e6-8201150358ef.png

翻阅资料后,得知JDK8中,-XX:MaxMetaspaceSize是没有上限的,与机器内存相关,但初始的默认值只有21M,所以得出结论是,因为metaspace空间不足导致发生了FullGC

解决方案

JDK1.8之后,永久代(PermGen)概念被废弃掉了,取而代之的是Metaspace的存储空间,它使用的是本地内存,而不是堆内存,它的大小与本地内存有关。

最终通过设置JVM启动参数-XX:MetaspaceSize=256M 解决了该问题。

-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m

67c2b55d-cdd2-49ff-8b6f-b7161a6f422b.png

483f328d-9221-4050-9567-706abed2d98d.png

目录
相关文章
|
12月前
|
Java
jvisualvm安装并查看GC过程
jvisualvm安装并查看GC过程
129 0
|
3月前
|
监控 JavaScript Java
JVM源码级别分析G1发生FullGC元凶的是什么
线上系统遭遇频繁Old GC问题,监控显示出现多次“to-space exhausted”日志,这表明垃圾回收过程中因年轻代 Survivor 区或老年代空间不足导致对象晋升失败。通过 JVM 源码分析,此问题源于对象转移至老年代失败时,JVM 无法找到足够的空间存放存活对象。进一步排查发现大对象分配占用了预留空间,加剧了空间不足的情况。使用 JFR 分析工具定位到定期报表序列化导致大量大对象生成,通过改用堆外内存进行序列化输出,最终解决了频繁 Old GC 问题。
WXM
|
4月前
|
存储 缓存 运维
一场FullGC故障排查
本文档详细记录了一次线上Java应用因频繁Full GC导致CPU使用率异常升高的问题排查与解决过程。
WXM
176 3
|
3月前
|
存储 缓存 运维
有关一次FullGC的故障排查
在收到容器CPU使用率达到104%的告警后,通过日志发现多个线程正在进行批处理任务。初步怀疑Full GC导致CPU占用过高,但内存使用率仅为62%,不符合预期。进一步排查发现监控指标与实际情况不符,最终确认是由于JVM Full GC引起的CPU激增。通过分析堆内存快照,定位到四个大型`List<Map<String, String>>`对象占用了近900MB内存,这些对象由用户上传的Excel转换而来,导致内存膨胀。这些大对象在JVM中长时间驻留,容易触发Full GC。 为解决此问题,提出了两种方案: 1. 将数据存储于缓存而非JVM内存中; 2. 减少内存中对象的数据量,如删除无用字
|
4月前
|
Java 运维
开发与运维内存问题之触发Full GC,类加载检查如何解决
开发与运维内存问题之触发Full GC,类加载检查如何解决
32 0
|
5月前
|
运维 Java Shell
手工触发Full GC:JVM调优实战指南
本文是关于Java应用性能调优的指南,重点介绍了如何使用`jmap`工具手动触发Full GC。Full GC是对堆内存全面清理的过程,通常在资源紧张时进行以缓解内存压力。文章详细阐述了Full GC的概念,并提供了两种使用`jmap`触发Full GC的方法:通过`-histo:live`选项获取存活对象统计信息,或使用`-dump`选项生成堆转储文件以分析内存状态。同时,文中也提醒注意手动Full GC可能带来的性能开销,建议在生产环境中谨慎操作。
1445 1
|
5月前
|
Arthas 监控 Java
线上频繁fullgc问题-SpringActuator的坑
偷偷开启的监控在吃内存
101 0
|
Java
如何优化生产环境的Full GC?
大部分工程师开发完一个系统后,部署生产环境的时候往往不对JVM进行参数设置,直接用默认JVM参数,这绝对是系统负载逐渐增高的时最大问题 如你不设置-Xmx、-Xms之类的堆内存大小,你启动一个系统,可能默认就给你几百MB的堆内存大小,新生代和老年代可能都是几百M。
164 0
|
存储 数据可视化 Go
记一次线上Go服务内存占用异常问题排查
记一次线上Go服务内存占用异常问题排查
486 0
记一次线上Go服务内存占用异常问题排查
|
缓存 Java
JVM频繁fullgc优化策略
JVM频繁fullgc优化策略
172 0