这篇博客会先容如何通过JMX 来获取Java 历程占用的CPU操作率和GC所占用的CPU操作率
在利用JVisualVM的时候,发明它可以查察当前JAVA 历程占用的CPU操作率和GC 所占用的CPU操作率,很奇怪它是如何计较的可能怎么获取的.
本文会按照JVisualVM的源码来描写JVisualVM是如何计较的.
获取源码
GITHUB 地点: https://github.com/visualvm/visualvm.src
百度云:http://pan.baidu.com/s/1boHI4HL
方针数据
运行jvisualvm, 方针是获取图中的CPU Usage 和 GC activity.
HOW TO
将源码导入Intellij后,可以全局搜索GC activity,然后可以查察到:
在Bundle.properties 中:
LBL_Gc_Usage=GC activity
然后查察这个property的利用处所:
com.sun.tools.visualvm.application.views.monitor.ApplicationMonitorView.CpuViewSupport ... private static final String CPU = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Cpu"); // NOI18N private static final String CPU_USAGE = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Cpu_Usage"); // NOI18N private static final String GC_USAGE = NbBundle.getMessage(ApplicationMonitorView.class, "LBL_Gc_Usage"); // NOI18N ... private void initModels(ApplicationMonitorModel model) { liveModel = model.isLive(); processorsCount = model.getProcessorsCount(); cpuMonitoringSupported = model.isCpuMonitoringSupported(); gcMonitoringSupported = model.isGcMonitoringSupported(); SimpleXYChartDescriptor chartDescriptor = //下面的这个后头会讲到 SimpleXYChartDescriptor.percent(false, 0.1d, model.getChartCache()); chartDescriptor.addLineItems(CPU_USAGE, GC_USAGE); chartDescriptor.setDetailsItems(new String[] { CPU_USAGE, GC_USAGE }); chartSupport = ChartFactory.createSimpleXYChart(chartDescriptor); //这里就应该就是界面显示的注册了. 那么注册后是如何利用的??? model.registerCpuChartSupport(chartSupport); chartSupport.setZoomingEnabled(!liveModel); }
主要的计较逻辑会合在其refresh要领中:
public void refresh(ApplicationMonitorModel model) { //假如监控CPU if (cpuMonitoringSupported || gcMonitoringSupported) { //获取当前的UPTIME long upTime = model.getUpTime() * 1000000; //获取上次的UPTIME long prevUpTime = model.getPrevUpTime() * 1000000; boolean tracksProcessCpuTime = cpuMonitoringSupported && model.getPrevProcessCpuTime() != -1; //获取当前的CPU时间 long processCpuTime = tracksProcessCpuTime ? model.getProcessCpuTime() / processorsCount : -1; //获取上次的CPU时间 long prevProcessCpuTime = tracksProcessCpuTime ? model.getPrevProcessCpuTime() / processorsCount : -1; boolean tracksProcessGcTime = gcMonitoringSupported && model.getPrevProcessGcTime() != -1; //获取当前的GC占用时间 long processGcTime = tracksProcessGcTime ? model.getProcessGcTime() * 1000000 / processorsCount : -1; //获取上次的GC占用时间 long prevProcessGcTime = tracksProcessGcTime ? model.getPrevProcessGcTime() * 1000000 / processorsCount : -1; if (prevUpTime != -1 && (tracksProcessCpuTime || tracksProcessGcTime)) { long upTimeDiff = upTime - prevUpTime; //别离计较CPU利用率和GC的CPU利用率. long cpuUsage = -1; long gcUsage = -1; String cpuDetail = UNKNOWN; String gcDetail = UNKNOWN; if (tracksProcessCpuTime) { long processTimeDiff = processCpuTime - prevProcessCpuTime; cpuUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processTimeDiff / (float)upTimeDiff), 1000) : 0; cpuDetail = cpuUsage == -1 ? UNKNOWN : chartSupport.formatPercent(cpuUsage); } if (tracksProcessGcTime) { long processGcTimeDiff = processGcTime - prevProcessGcTime; gcUsage = upTimeDiff > 0 ? Math.min((long)(1000 * (float)processGcTimeDiff / (float)upTimeDiff), 1000) : 0; if (cpuUsage != -1 && cpuUsage < gcUsage) gcUsage = cpuUsage; gcDetail = gcUsage == -1 ? UNKNOWN : chartSupport.formatPercent(gcUsage); } if (liveModel) //配置视图的值 到达刷新的目标 //可以看到这个值和界面上显示是相差0.1倍的 原因是前面的谁人chartDescriptor 有个0.1d的显示倍率. chartSupport.addValues(model.getTimestamp(), new long[] { Math.max(cpuUsage, 0), Math.max(gcUsage, 0) }); chartSupport.updateDetails(new String[] { cpuDetail, gcDetail }); } } }
可以看到逻辑主要是ApplicationMonitorModel model工具的相关要领中,下面先容这些时间是如何获取的:
ApplicationMonitorModel的要领: