症状
JVM 以 OutOfMemoryError: Metaspace 失败,而堆用量正常。Metaspace 存放类元数据,因此增长来自类被加载却从不卸载。这常发生在同一 JVM 中反复重部署应用之后,或运行期生成类的框架(如代理与表达式库)之中,每次生成都消耗 Metaspace,只有其类加载器不可达时才回收。
诊断
用 -Xlog:class+load 观察类加载;用 jcmd VM.metaspace 跟踪用量;搜索动态生成类的位置。
java -Xlog:class+load=info -jar app.jar
根因
Metaspace 被填满,因为类及其类加载器被保留,通常源于反复动态生成类或同一 JVM 内重部署,导致已加载的类从未卸载。
修复
限制或缓存运行期生成的类,重部署时释放类加载器,避免无界地创建动态代理。按合理类数量设 Metaspace 上限,但先确认增长是泄漏而非应用本身够大。
验证
重跑确认已加载类数量稳定、Metaspace 用量趋于平台,且错误不再出现。持续负载下类数量趋于平稳即证明泄漏已除。
常见陷阱
把 Metaspace 设成无限只是把崩溃推迟;应定位保留类加载器的引用。