最明确的信号是日志中出现java.lang.OutOfMemoryError: Metaspace,表明元空间耗尽导致无法加载新类;需检查GC日志中Metaspace与Full GC是否高频共现、MaxMetaspaceSize配置是否合理、类加载是否失控,并通过压测确定合适阈值。

直接看日志里有没有 java.lang.OutOfMemoryError: Metaspace,这是最明确的信号。它说明元空间已耗尽,JVM 无法加载新类——不是堆内存不够,也不是磁盘空间不足,而是元空间配置或类加载行为出了问题。
查日志里 Metaspace 和 Full GC 是否高频共现
元空间满不一定会立刻 OOM,但会频繁触发 Full GC 来尝试卸载类。重点检查 GC 日志中是否出现以下组合:
- 连续多次
Full GC (Metadata GC Threshold)或Full GC (System.gc()) - 每次 Full GC 后,
Metaspace区域的used值几乎没降,甚至还在涨 - JDK 11+ 日志中带
Metaspace标签的行反复出现,且capacity持续增长(说明在动态扩容)
确认 MaxMetaspaceSize 配置是否合理
用命令快速验证当前设置:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
jinfo -flag MaxMetaspaceSize <pid>:返回-1表示未设上限;返回具体值(如256m)则需结合业务类数量判断是否偏小 - 对比同构服务:若其他稳定运行的实例设了
512m,而故障实例仍用默认值(通常仅 20–50MB),基本可锁定配置过小 - 注意
-XX:MetaspaceSize是否缺失:没设该参数会导致首次扩容就触发 Full GC,加剧压力
定位谁在疯狂加载类
配置不当往往是表象,背后常是类加载失控。临时加参数抓线索:
立即学习“Java免费学习笔记(深入)”;
- 启动时加
-XX:+TraceClassLoading -XX:+TraceClassUnloading,复现问题后用grep "Loaded" trace.log | wc -l统计加载量 - 用
jcmd <pid> VM.class_hierarchy或jmap -clstats <pid>查看哪个 ClassLoader 加载了上千个类(重点关注WebAppClassLoader、RestartClassLoader等) - 配合
jstat -gc <pid>观察MU(Metaspace used)是否持续逼近MC(Metaspace capacity),且MC缓慢上涨
用压测数据定最终阈值
别靠经验猜,要拿真实负载说话:
- 在准生产环境做压测,用
jstat -gc <pid> 1000持续监控,记录MU的峰值 - 取峰值的 1.5–2 倍作为
-XX:MaxMetaspaceSize初始值(例如峰值 300MB → 设 512MB) - 上线后观察:若
MU长期稳定在MC的 70% 以下,说明配置合理;若仍频繁触顶,说明存在类泄漏,得深挖 ClassLoader 引用链

















