上一期的javaagent实现了采集jvm指标的能力,这一期我们增加性能调试功能,主要包括我们性能分析最常用的手段:dump堆栈,dump JFR,打印线程。实现方案仍然是调用JMX的相关MBean接口
打印线程:
打印线程栈一般用jstack,用代码可以用DiagnosticCommandMBean
public void printThread(){
DiagnosticCommandMBean diagnosticCommandMBean = ManagementFactoryHelper.getDiagnosticCommandMBean();
Object res = null;
try {
res = diagnosticCommandMBean.invoke("threadPrint", new Object[]{new String[]{}}, new String[]{String[].class.getName()});
} catch (MBeanException e) {
e.printStackTrace();
} catch (ReflectionException e) {
e.printStackTrace();
}
System.out.println(res);
}
image.png
输出结果是和jstack一样的
dump JFR
JFR是性能分析中常用手段,导出JFR后,可以生成火焰图,也可以用jmc或jprofile等工具进行性能分析。导出JFR需要执行三个命令,分别是解锁,开始JFR,结束JFR
到处JFR一般用jcmd,代码用DiagnosticCommandMBean
public void dumpJfr(){
DiagnosticCommandMBean diagnosticCommandMBean = ManagementFactoryHelper.getDiagnosticCommandMBean();
Object res = null;
try {
res = diagnosticCommandMBean.invoke("vmUnlockCommercialFeatures",
new Object[]{new String[]{}}, new String[]{String[].class.getName()});
System.out.println(res);
res = diagnosticCommandMBean.invoke("jfrStart",
new Object[]{new String[]{}}, new String[]{String[].class.getName()});
System.out.println(res);
Thread.sleep(30000);
res = diagnosticCommandMBean.invoke("jfrStop",
new Object[]{new String[]{"recording=1","filename=123.jfr"}}, new String[]{String[].class.getName()});
System.out.println(res);
} catch (MBeanException e) {
e.printStackTrace();
} catch (ReflectionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
image.png
dump heap
导出堆内存一般用jmap或jcmd,代码可以用HotSpotDiagnosticMXBean
生成dump文件可以用JVisualVM等工具打开分析
public void dumpHeap() throws IOException {
HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean = ManagementFactoryHelper.getDiagnosticMXBean();
List<VMOption> vmOptions = hotSpotDiagnosticMXBean.getDiagnosticOptions();
System.out.println(vmOptions);
hotSpotDiagnosticMXBean.dumpHeap("heap.dump",true);
}














网友评论