code cache用于存储jit编译的机器码,满则停编译致性能骤降;需用jstat -compiler查failed增长、-xx:reservedcodecachesize扩容并配合-xx:+usecodecacheflushing清理。

Java 中 JVM 的代码缓存区(Code Cache)用于存储 JIT 编译器生成的本地机器码。当热点方法被频繁执行,JIT 会将其编译为高效机器码并放入 Code Cache;若缓存不足,编译会被暂停或降级,导致性能回落——比如方法长期停留在解释执行模式,响应变慢、吞吐下降。
确认是否受限于 Code Cache
先观察实际运行中是否触发了 Code Cache 耗尽警告或编译抑制:
- 启动时添加 -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintCodeCache,运行一段时间后查看日志中是否有
CodeCache is full或made not entrant等提示 - 使用 jstat -compiler
查看 failed编译次数是否持续增长 - 通过 jcmd
VM.native_memory summary 或 jconsole → VM Summary → Code Cache 查看实时占用率(长期 >90% 就需干预)
调整 Code Cache 初始与最大大小
JVM 默认 Code Cache 大小在不同版本差异较大(如 JDK 8 约 48MB,JDK 17+ 默认 240MB),但高并发、多模块、AOP/反射密集型应用极易撑满。推荐显式配置:
- -XX:InitialCodeCacheSize=256m:避免启动初期反复扩容抖动
- -XX:ReservedCodeCacheSize=512m(JDK 10+ 推荐用 -XX:MaxCodeCacheSize):设为上限,防止无节制增长影响其他内存区域
- 若应用含大量动态类(如 Spring Boot + CGLIB、Groovy 脚本),可进一步设为 -XX:MaxCodeCacheSize=1g
配合 JIT 编译策略协同优化
单纯扩大 Code Cache 不解决根本问题;需确保编译行为高效、稳定:
- 启用分层编译:-XX:+TieredCompilation(JDK 8u60+ 默认开启),让方法先经 C1 快速编译,再根据热度升级到 C2 深度优化
- 避免过早禁用编译:-XX:-UseCompiler 或 -XX:CompileThreshold 设得过高,会导致热点方法迟迟不编译
- 监控编译队列积压:jstat -compiler
中 total增长快但compiled滞后,说明编译线程瓶颈,可考虑 -XX:CICompilerCount=4(默认 2,多核服务器可适度增加)
其他辅助手段
减少无效编译开销,间接缓解 Code Cache 压力:
- 关闭调试符号生成:-XX:-Debugging(生产环境无需调试信息)
- 限制内联深度(防过度膨胀):-XX:MaxInlineLevel=15(默认 9,谨慎调高)
- 对已知冷代码主动排除编译:-XX:CompileCommand=exclude,com.example.Service::unneededMethod
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











