您现在的位置是:首页 > 文章详情

JVM Profiler CpuAndMemoryProfiler

日期:2018-09-04点击:369

开篇

CpuAndMemoryProfiler主要用来采集cpu和memory相关的信息,采集核心方法都是由ManagementFactory提供的接口:

  • getClassLoadingMXBean() 返回 Java 虚拟机的类加载系统的管理 Bean。
  • getCompilationMXBean() 返回 Java 虚拟机的编译系统的管理 Bean。
  • getGarbageCollectorMXBeans() 返回 Java 虚拟机中的 GarbageCollectorMXBean 对象列表。
  • getMemoryManagerMXBeans() 返回 Java 虚拟机中的 MemoryManagerMXBean 对象列表。
  • getMemoryMXBean() 返回 Java 虚拟机的内存系统的管理 Bean。
  • getMemoryPoolMXBeans() 返回 Java 虚拟机中的 MemoryPoolMXBean 对象列表。
  • getOperatingSystemMXBean() 返回运行 Java 虚拟机的操作系统的管理 Bean。
  • getPlatformMBeanServer() 返回平台 MBeanServer。
  • getRuntimeMXBean() 返回 Java 虚拟机的运行时系统的管理 Bean。
  • getThreadMXBean() 返回 Java 虚拟机的线程系统的管理 Bean。


源码分析

采集器核心对象的初始化

  • 通过ManagementFactory.getPlatformMBeanServer初始化platformMBeanServer。
  • 通过ObjectName.getInstance()初始化operatingSystemObjectName。
public class CpuAndMemoryProfiler extends ProcessInfoBase implements Profiler { public final static String PROFILER_NAME = "CpuAndMemory"; private static final AgentLogger logger = AgentLogger.getLogger(CpuAndMemoryProfiler.class.getName()); private static final String ATTRIBUTE_NAME_ProcessCpuLoad = "ProcessCpuLoad"; private static final int ATTRIBUTE_INDEX_ProcessCpuLoad = 0; private static final String ATTRIBUTE_NAME_SystemCpuLoad = "SystemCpuLoad"; private static final int ATTRIBUTE_INDEX_SystemCpuLoad = 1; private static final String ATTRIBUTE_NAME_ProcessCpuTime = "ProcessCpuTime"; private static final int ATTRIBUTE_INDEX_ProcessCpuTime = 2; private long intervalMillis = Constants.DEFAULT_METRIC_INTERVAL; private MBeanServer platformMBeanServer; private ObjectName operatingSystemObjectName; private MemoryMXBean memoryMXBean; private Reporter reporter; public CpuAndMemoryProfiler(Reporter reporter) { setReporter(reporter); init(); } private void init() { try { platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); operatingSystemObjectName = ObjectName.getInstance("java.lang:type=OperatingSystem"); } catch (Throwable ex) { logger.warn("Failed to get Operation System MBean", ex); } try { memoryMXBean = ManagementFactory.getMemoryMXBean(); } catch (Throwable ex) { logger.warn("Failed to get Memory MBean", ex); } } 

属性采集过程

  • ManagementFactory.getPlatformMBeanServer().getAttributes()获取cpu属性
  • ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()获取堆使用属性。
  • ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()获取非堆的使用属性。
  • ManagementFactory.getGarbageCollectorMXBeans()获取内存使用属性。
  • ManagementFactory.getPlatformMXBeans()回去实例对象的属性。
  • 通过读取/proc/self/status文件来获取进程状态属性。
  • 组装所有参数上报。
 public synchronized void profile() { Double processCpuLoad = null; Double systemCpuLoad = null; Long processCpuTime = null; // 获取cpu属性 getCpuAttributes,通过platformMBeanServer对象来获取 AttributeList cpuAttributes = getCpuAttributes(); if (cpuAttributes != null && cpuAttributes.size() > 0) { Attribute att = (Attribute) cpuAttributes.get(ATTRIBUTE_INDEX_ProcessCpuLoad); processCpuLoad = (Double) att.getValue(); if (processCpuLoad == Double.NaN) { processCpuLoad = null; } att = (Attribute) cpuAttributes.get(ATTRIBUTE_INDEX_SystemCpuLoad); systemCpuLoad = (Double) att.getValue(); if (systemCpuLoad == Double.NaN) { systemCpuLoad = null; } att = (Attribute) cpuAttributes.get(ATTRIBUTE_INDEX_ProcessCpuTime); processCpuTime = (Long) att.getValue(); } // 获取memory属性,通过memoryMXBean对象来获取 Double heapMemoryTotalUsed = null; Double heapMemoryCommitted = null; Double nonHeapMemoryTotalUsed = null; Double nonHeapMemoryCommitted = null; if (memoryMXBean != null) { MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage(); heapMemoryTotalUsed = new Double(memoryUsage.getUsed()); heapMemoryCommitted = new Double(memoryUsage.getCommitted()); memoryUsage = memoryMXBean.getNonHeapMemoryUsage(); nonHeapMemoryTotalUsed = new Double(memoryUsage.getUsed()); nonHeapMemoryCommitted = new Double(memoryUsage.getCommitted()); } List<Map<String, Object>> gcMetrics = new ArrayList<>(); // 获取垃圾回收对象,通过ManagementFactory.getGarbageCollectorMXBeans()来实现 List<GarbageCollectorMXBean> gcMXBeans = ManagementFactory.getGarbageCollectorMXBeans(); if (gcMXBeans != null) { for (GarbageCollectorMXBean gcMXBean : gcMXBeans) { Map<String, Object> gcMap = new HashMap<>(); gcMap.put("name", gcMXBean.getName()); gcMap.put("collectionCount", new Long(gcMXBean.getCollectionCount())); gcMap.put("collectionTime", new Long(gcMXBean.getCollectionTime())); gcMetrics.add(gcMap); } } // 获取memoryPoolsMetrics指标,通过ManagementFactory.getMemoryPoolMXBeans())来实现 List<Map<String, Object>> memoryPoolsMetrics = new ArrayList<>(); for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { Map<String, Object> memoryPoolMap = new HashMap<>(); memoryPoolMap.put("name", pool.getName()); memoryPoolMap.put("type", pool.getType().toString()); memoryPoolMap.put("usageCommitted", pool.getUsage().getCommitted()); memoryPoolMap.put("usageMax", pool.getUsage().getMax()); memoryPoolMap.put("usageUsed", pool.getUsage().getUsed()); memoryPoolMap.put("peakUsageCommitted", pool.getPeakUsage().getCommitted()); memoryPoolMap.put("peakUsageMax", pool.getPeakUsage().getMax()); memoryPoolMap.put("peakUsageUsed", pool.getPeakUsage().getUsed()); memoryPoolsMetrics.add(memoryPoolMap); } // 获取bufferPoolsMetrics指标,通过ManagementFactory.getPlatformMXBeans()来实现 List<Map<String, Object>> bufferPoolsMetrics = new ArrayList<>(); List<BufferPoolMXBean> bufferPools = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class); if (bufferPools != null) { for (BufferPoolMXBean pool : bufferPools) { Map<String, Object> bufferPoolMap = new HashMap<>(); bufferPoolMap.put("name", pool.getName()); bufferPoolMap.put("count", new Long(pool.getCount())); bufferPoolMap.put("memoryUsed", new Long(pool.getMemoryUsed())); bufferPoolMap.put("totalCapacity", new Long(pool.getTotalCapacity())); bufferPoolsMetrics.add(bufferPoolMap); } } // 获取procStatus指标,通过ProcFileUtils.getProcStatus()来实现 Map<String, String> procStatus = ProcFileUtils.getProcStatus(); Long procStatusVmRSS = ProcFileUtils.getBytesValue(procStatus, "VmRSS"); Long procStatusVmHWM = ProcFileUtils.getBytesValue(procStatus, "VmHWM"); // 组装所有采集结果进行上报 Map<String, Object> map = new HashMap<String, Object>(); map.put("epochMillis", System.currentTimeMillis()); map.put("name", getProcessName()); map.put("host", getHostName()); map.put("processUuid", getProcessUuid()); map.put("appId", getAppId()); if (getTag() != null) { map.put("tag", getTag()); } if (getCluster() != null) { map.put("cluster", getCluster()); } if (getRole() != null) { map.put("role", getRole()); } map.put("processCpuLoad", processCpuLoad); map.put("systemCpuLoad", systemCpuLoad); map.put("processCpuTime", processCpuTime); map.put("heapMemoryTotalUsed", heapMemoryTotalUsed); map.put("heapMemoryCommitted", heapMemoryCommitted); map.put("nonHeapMemoryTotalUsed", nonHeapMemoryTotalUsed); map.put("nonHeapMemoryCommitted", nonHeapMemoryCommitted); map.put("gc", gcMetrics); map.put("memoryPools", memoryPoolsMetrics); map.put("bufferPools", bufferPoolsMetrics); if (procStatusVmRSS != null) { map.put("vmRSS", procStatusVmRSS); } if (procStatusVmHWM != null) { map.put("vmHWM", procStatusVmHWM); } if (reporter != null) { reporter.report(PROFILER_NAME, map); } } 

cpu属性的获取过程

  • platformMBeanServer.getAttributes()方法用来获取cpu的信息。
 private AttributeList getCpuAttributes() { try { String[] names = new String[]{ATTRIBUTE_NAME_ProcessCpuLoad, ATTRIBUTE_NAME_SystemCpuLoad, ATTRIBUTE_NAME_ProcessCpuTime}; AttributeList list = platformMBeanServer.getAttributes(operatingSystemObjectName, names); if (list.size() != names.length) { logger.warn("Failed to get all attributes"); return new AttributeList(); } return list; } catch (Throwable ex) { logger.warn("Failed to get CPU MBean attributes", ex); return null; } } } 

进程状态获取

  • 通过读取/proc/self/status文件来获取进程信息。
 private static final String PROC_SELF_STATUS_FILE = "/proc/self/status"; public static Map<String, String> getProcStatus() { return getProcFileAsMap(PROC_SELF_STATUS_FILE); } public static Map<String, String> getProcFileAsMap(String filePath) { try { File file = new File(filePath); if (!file.exists() || file.isDirectory() || !file.canRead()) { return Collections.emptyMap(); } Map<String, String> result = new HashMap<>(); List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8); for (String line : lines) { int index = line.indexOf(VALUE_SEPARATOR); if (index <= 0 || index >= line.length() - 1) { continue; } String key = line.substring(0, index).trim(); String value = line.substring(index + 1).trim(); result.put(key, value); } return result; } catch (Throwable ex) { logger.warn("Failed to read file " + filePath, ex); return Collections.emptyMap(); } } 


参考文章

ManagementFactory api

原文链接:https://yq.aliyun.com/articles/666299
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章