一台服务器的CPU使用率逐渐下降到100%,我发现CodeCache区域占用了231M,而阈值是240M。
我的集群中的其他服务器很好,CPU使用率为30%,CodeCache区域占用了110M。
我想知道在服务器无法重新启动时,CodeCache 区域中存储了哪些编译代码以避免破坏场景。
它是否存在代码缓存转储?
PS:JDK版本是1.8
对于更新的 JDK 版本,您可以使用 jcmd Compiler.codecache
和 jcmd Comiler.codelist
。对于 1.8,请尝试 -XX:+PrintCodeCache 或 –XX:+PrintCodeCacheOnCompilation,尽管这只会为您提供摘要统计信息(请参阅有没有办法监视 Java 中编译的代码缓存?(。
jcmd codelist
命令由 JVM 的 CodeCache::print_codelist
方法处理,但这在 JDK 8 中不可用 - 所有内容都是print_summary
。
PS:我也尝试使用gcore
生成核心转储,但未能看到如何以这种方式分析代码缓存。
这是一个简单的程序,可用于在JDK 8上转储CodeCache。
import sun.jvm.hotspot.code.CodeBlob;
import sun.jvm.hotspot.code.CodeCacheVisitor;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;
public class DumpCodeCache extends Tool {
@Override
public void run() {
VM.getVM().getCodeCache().iterate(new CodeCacheVisitor() {
public void prologue(Address start, Address end) {
}
public void visit(CodeBlob blob) {
System.out.printf("%8d %sn", blob.getSize(), blob.getName());
}
public void epilogue() {
}
});
}
public static void main(String[] args) {
new DumpCodeCache().execute(args);
}
}
该工具基于Serviceabiliy Agent技术。
若要编译并运行它,请在类路径中包含$JAVA_HOME/lib/sa-jdi.jar
。
java -cp $JAVA_HOME/lib/sa-jdi.jar:. DumpCodeCache PID
从 JDK 9 开始,有一个内置功能可以使用 jcmd 转储 CodeCache:
jcmd PID Compiler.codelist
从 JDK 11 开始,还有更强大的命令来打印详细的 CodeCache 统计信息:
jcmd PID Compiler.CodeHeap_Analytics