CompressedClassSpace是与Metaspace并列的独立本地内存区,专存Klass结构体(约2KB/类),不参与GC,耗尽时抛OutOfMemoryError: Compressed class space;需显式配置-XX:CompressedClassSpaceSize且不可动态扩容。

CompressedClassSpace(压缩类空间)不是元空间的子区域,而是与元空间并列、独立分配的一块本地内存区。它不存字节码、常量池或方法签名等完整元数据,只存放每个已加载类对应的轻量级 Klass 结构体(典型大小约 2KB),可理解为“类的运行时索引头”。它的存在前提是启用了压缩类指针(-XX:+UseCompressedClassPointers),默认在 JDK 8u60+ 中开启。
为什么需要单独关注 CompressedClassSpace
元空间(Metaspace)和 CompressedClassSpace 各自耗尽会触发不同错误:
- java.lang.OutOfMemoryError: Metaspace → 类元数据本身过多(如大量动态代理字节码)
- java.lang.OutOfMemoryError: Compressed class space → Klass 实例数量超限(如 Spring AOP 生成数千切面类、CGLIB 批量创建代理类)
两者内存物理隔离、容量互不影响:调大 -XX:MaxMetaspaceSize 无法缓解 CompressedClassSpace 耗尽;同样,增大 CompressedClassSpace 也不能降低 Metaspace 压力。
容量配置的关键规则
该空间大小由 -XX:CompressedClassSpaceSize 显式设定,启动即按此值固定 commit,不可动态扩容,也不参与 GC 回收。
立即学习“Java免费学习笔记(深入)”;
- 必须配合 -XX:+UseCompressedClassPointers 使用,否则该参数无效
- 推荐设为 2MB 的整数倍(如 256m、512m、1g),避免 JVM 内部对齐失败
- 最大值受限于操作系统虚拟地址空间(x86_64 Linux 下通常 ≤ 32GB)
- 未显式设置时,默认为 1GB,但高动态类场景下极易成为瓶颈
如何验证与监控实际使用
运行时可通过以下方式确认配置是否生效及使用水位:
- 查参数:
jinfo -flag CompressedClassSpaceSize <pid>,输出应与启动参数一致 - 看使用率:
jstat -gc <pid>中关注 CCSU(used)与 CCSC(capacity)字段,持续 ≥90% 即需干预 - 查详情:
jcmd <pid> VM.metaspace或jcmd <pid> GC.heap_info,会分别列出 “class space” 和 “Metaspace”的用量
常见误判与应对建议
当新类加载失败但 Metaspace 仍有余量时,容易误判为元空间问题。此时应重点排查:
- 是否忽略 CCS 溢出信号,仅监控 Metaspace Used 而未看 CCS 使用率
- 是否依赖默认 1GB 配置,却在插件化/模块化/热更新场景中加载上万类
- 是否因设值过小(如 64m)导致大量 Klass 被迫降级存入普通 Metaspace,引发碎片与性能下降
若确认是 CCS 瓶颈,优先调整 -XX:CompressedClassSpaceSize 至合理值(例如 512m~2g),而非盲目扩大 MaxMetaspaceSize。


















