前言
我是[提前退休的java猿],一名7年java开发经验的开发组长,分享工作中的各种问题!(抖音、公众号同号)
🔈 今天这篇文章一定值得你看 转载前公司CTO发的文章:FullGC排查,居然是它
项目上有 Full GC 告警,每个节点平均每天有一到两次Full GC 告警。出现Full GC时,应用是处于 Stop The World 状态,对于高可用要求的应用来说,这是一个很大的稳定性风险。就在告警出现的这几天,上游业务方也联系到我,说他们近期调用我们的接口超时,通过监控来看,调用超时的时间正好也就是Full GC出现的时间。虽然我其实并没有排查过Full GC问题,不过我还是想试一下。
问题分析排查
通过查看Full GC日志,发现Full GC是由于达到Metaspace Threadhold
触发,GC耗时在2-4S。
js
2025-09-27T14:33:02.210+0800: 312596.342:
[FullGC(MetadataGCThreshold) 3169M->553M(6144M), 3.5247678secs]
[Eden: 1258.0M(3594.0M)->0.0B(3686.0M) Survivors: 22528.0K->0.0B Heap: 3169.3M(6144.0M)->554.0M(6144.0M)], [Metaspace: 752742K->303689K(1511424K)]
[Times: user=4.20 sys=0.43, real=3.52 secs]
既然是元空间,那我们通过应用监控查看当时的元空间情况,当Metaspace 达到700多MB时,就会触发Full GC, GC后元空间降到300多MB,释放了400M内存。
元空间主要是存放 class 信息,看一下类数量的监控,在FullGC时,类数量达到15万,GC后降低到4万,释放了11万个class。
正常情况下 class 是相对稳定的,通常是由于动态代理、序列化、脚本引擎这类场景会动态生成类。
通过类监控
的增长曲线发现,工作时间的类增长曲线明显比非工作时间的类增长曲线更陡峭,说明大概率是工作时间调用的某个接口的内部逻辑导致。
通过接口调用数量监控
,判断可能和其中三个接口有关。于是从接口调用入口出发捋代码逻辑,找到一段调用 Aviator
框架的代码。
java
AviatorEvaluatorInstance instance = ExpressContext.getInstance();
ExpressionLexer lexer = new ExpressionLexer(instance, expression);
CodeGenerator codeGenerator = new OptimizeCodeGenerator(instance, null, CLASS_LOADER, null);
ExpressionParser parser = new ExpressionParser(instance, lexer, codeGenerator);
parser.parse();
这段代码看着就可疑,又是CodeGenerator
,又用到ClassLoader
,这些类名仿佛就是在和我说,别找了,就是我。
于是写了一段单元测试代码,循环调用,jvm启动参数上加上
ruby
-XX:+TraceClassLoading -XX:+TraceClassUnloading
运行后发现有大量类的生成和卸载,完全满足触发 Metapsace Threshold 的条件。此时此刻,我已经有80%的把握就是它的问题了。不过熟悉我的人都知道,我不仅是一个解决问题能力还不错的人,同时我还是一个保守的人, 没有十足的把握我是不会下结论,我可不想在新团队砸了自己招牌。

现在一切猜想都很符合逻辑,现在就差最后的证明,那就是类统计信息。在这不像我以前的时候,各种环境我都是超管权限,想怎么弄就怎么弄。我无法登录到容器内部用jcmd或者 jmap histo命令去统计类,容器平台上提供了堆dump的功能,但是堆dump是一个非常重量级的操作,为了不影响业务,我只能等。
在国庆期间,大家都休假了,我做了一个决定,我偷偷的登录到云平台,关闭其中一个节点的流量,导出堆内存,导入MAT进行分析。此时我心情是平静的,我知道我对了,我只是要让MAT告诉我。我本将心向明月,然明月何曾是两乡,MAT没有辜负我,它小声的和我说:你对了。

解决方案
这些类就是Aviator框架生成的,类名后缀是顺序递增,总共生成过100多万个class。解决方案通过增加表达式的LRU缓存解决这个问题,上线后类数量非常平稳,Full GC也消失了。加LRU缓存也只是临时方案,最好是Aviator官方能支持我这种场景,给他们提了issue,不过大概率他们是不会同意的,毕竟它也只是一个个人项目,靠爱发电不太靠得住。你看我,想啥时候发就啥时候发。