一台服务器的CPU使用率逐渐达到100%,我发现CodeCache区域占用231M,而阈值是240M。
集群中的其他服务器很好,CPU使用率为30%,CodeCache区域占用了110M。
我想知道什么已编译的代码存储在CodeCache区域中,而服务器无法重新启动以避免破坏现场。
是否存在代码缓存转储?
ps:jdk版本为1.8
答案 0 :(得分:1)
使用最新的JDK版本,您可以使用jcmd Compiler.codecache
和 jcmd Comiler.codelist
。
对于1.8,请尝试-XX:+ PrintCodeCache或–XX:+ PrintCodeCacheOnCompilation,尽管这只会给您提供摘要统计信息(请参阅Is there any way to monitor the compiled code cache in Java?)。
jcmd codelist
命令由JVM的CodeCache::print_codelist
方法处理,但是在JDK 8中不可用-仅有print_summary
。
PS:我也尝试过使用gcore
生成核心转储,但是看不到如何以这种方式分析代码缓存。
答案 1 :(得分:1)
这是一个简单的程序,可用于在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 %s\n", 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