http://songzi0206.iteye.com/blog/1541636

********************

从JAVA 5开始,JDK提供了一些JVM检测的API,这就是有名的java.lang.management 包,包里提供了许多MXBean的接口类,可以很方便的获取到JVM的内存、GC、线程、锁、class、甚至操作系统层面的各种信息,本文就简单的介绍一种利用JMX对JAVA进程进行CPU、堆内存使用的监控。可能有人会觉得没必要这样做,因为用jconsole之类的工具都能做到,而且会比本文的例子更详细。但是有些时候将console不一定能监控到作为系统服务的java进程,我最近就不得不自己编码去获取远程java进程的监控数据。希望能起到抛砖引玉的作用吧。

首先,简要介绍下JMX(Java Management Extensions),即JAVA管理扩展,用来监视和管理JVM以及其运行的操作系统。目前java平台主要提供了下图所示的9个MXBean, 各个MXBean的作用根据类名大概能猜出几分,具体可查API。

java.lang.management包中的mxbean提供了基本的功能,在sum.com.management中对某些功能有所增强,当然我们也可以根据JMX规范提供自己的MXBean。

下面我主要使用java.lang.management.MemoryMXBean和sun.com.management.OperatingSystemMXBean分别对远程JAVA进行内存和cpu的监控。根据需求5秒钟读取一次数据,内存主要是已使用的Heap
Memory,CPU主要就是使用率了。

在使用OperatingSystemMXBean以及MemoryMXBean之前,首先必须得到JMXConnector并创建MBeanServerConnnection,有了这个connection我们就可以利用ManagementFactory创建需要的MXBean了,类依赖图如下:


        示例代码:

  1. /*
  2. * host: 远程机器的ip地址
  3. * port: 远程java进程运行的jmxremote端口
  4. */
  5. JMXServiceURL serviceURL = new JMXServiceURL( host,port );
  6. JMXConnector conn = JMXConnectorFactory.connect(serviceURL);
  7. MBeanServerConnection mbs=conn.getMBeanServerConnection();
  8. //获取远程memorymxbean
  9. MemoryMXBean memBean=ManagementFactory.newPlatformMXBeanProxy
  10. (mbs,ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
  11. //获取远程opretingsystemmxbean
  12. com.sun.management.OperatingSystemMXBean opMXbean =
  13. ManagementFactory.newPlatformMXBeanProxy(mbs,
  14. ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);

然后,采集memory的数据就比较简单了,直接调用API获取:

  1. /**    Collect data every 5 seconds      */
  2. try {
  3. TimeUnit.SECONDS.sleep(5);
  4. } catch (InterruptedException e) {
  5. logger.error("InterruptedException occurred while MemoryCollector sleeping...");
  6. }
  7. MemoryUsage heap = memBean
  8. etHeapMemoryUsage();
  9. MemoryUsage nonHeap = memBean
  10. etNonHeapMemoryUsage();
  11. long heapSizeUsed = heap.getUsed();//堆使用的大小
  12. long nonHeapSizeUsed = nonHeap.getUsed();
  13. long heapCommitedSize = heap.getCommitted();
  14. long nonHeapCommitedSize = nonHeap.getCommitted();

采集CPU利用率需要自己计算一下,因为API只提供了获取cpu的使用时间,我得在两次系统时间间隔内获取两次CPU的使用时间,得到在该时间间隔内cpu使用的时间,相除即得到CPU的使用率,当然误差肯定存在。

  1. Long start = System.currentTimeMillis();
  2. long startT = opMXbean.getProcessCpuTime();
  3. /**    Collect data every 5 seconds      */
  4. try {
  5. TimeUnit.SECONDS.sleep(5);
  6. } catch (InterruptedException e) {
  7. logger.error("InterruptedException occurred while MemoryCollector sleeping...");
  8. }
  9. Long end = System.currentTimeMillis();
  10. long endT = opMXbean.getProcessCpuTime();
  11. //end - start 即为当前采集的时间单元,单位ms
  12. //endT - startT 为当前时间单元内cpu使用的时间,单位为ns
  13. //所以:double ratio = (entT-startT)/1000000.0/(end-start)/opMXbean.getAvailableProcessors()

核心代码就是这些了,当然,具体使用的话应该用单独的线程分别取cpu、memory数据,读取的数据需要写文件或者画图,监控时间长的话还要定时的将这些数据刷到磁盘文件或数据库中,等,这些都是题外话了。这边我写到excel中,然后在excel中图形展示,远程监控的程序不方便展示,仅仅来监控一段模拟cpu正弦曲线的程序
,来看看我监控到的数据(图形)是否和预期一致,并与jconsole采到的有何差异:

  1. public class SinCpu {
  2. public static final double TIME = 1000;
  3. /**
  4. * @param args the command line arguments
  5. */
  6. public static void main(String[] args) throws InterruptedException {
  7. new Thread(new SinTask()).start();
  8. }
  9. static class SinTask implements Runnable{
  10. @Override
  11. public void run() {
  12. double x = 0;
  13. double y = 0;
  14. while (true) {
  15. y = (Math.sin(x) + 1) * TIME / 2;
  16. doSomeSimpleWork(y);
  17. x += 0.1;
  18. try {
  19. Thread.sleep((long) (TIME - y));
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }
  25. private void doSomeSimpleWork(double y) {
  26. long startTime = System.currentTimeMillis();
  27. while ((System.currentTimeMillis() - startTime) < y) {
  28. }
  29. }
  30. }
  31. }

监控结果基本和预期一样,CPU数据图呈现预期的正弦曲线:

上图中,第一个图是从jconsole监控图中截过来的,而下图是我利用opMXBean计算获得,两个图基本吻合,数据基本波动在0-25%是因为我测试机器是四核的cpu,两个图像之间有位移是因为,我手动打开jconsole没有我程序监控来的快,所以大概图像平移下基本吻合。

内存的测试应该比CPU还要准一些,这里就不贴了。Note: 如果监控的程序线程数量很大,cpu会有较明显误差,而且采的频率不够高的话可能有些点漏采。

最后:被测程序必须开放JMXREMOTE端口,具体使用参数:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=[开放的端口]
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

 

利用JMX统计远程JAVA进程的CPU和Memory的更多相关文章

  1. 利用JMX统计远程JAVA进程的CPU和Memory---jVM managerment API

    从JAVA 5开始,JDK提供了一些JVM检测的API,这就是有名的java.lang.management 包,包里提供了许多MXBean的接口类,可以很方便的获取到JVM的内存.GC.线程.锁.c ...

  2. JVM探秘:VisualVM监控远程Java进程

    VisualVM在Java 8中是JDK自带的一个图形化工具,项目主页 VisualVM,在后续版本中可能会从JDK移除. VisualVM可以监控Java进程的CPU与内存占用情况,可以监控Java ...

  3. JVM调优之Java进程消耗CPU过高

    JVM调优之Java进程消耗CPU过高 查找问题思路 1.查看cpu使用率,发现有线程cpu占用率很高  tops 咱们拿18092线程举例示范 2.查询pid对应的进程 ps -ef|grep 18 ...

  4. Java进程占用CPU资源过多分析

    问题描述: 生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析: 1,程序属于CPU密集型,和开发沟通 ...

  5. 生产环境下JAVA进程高CPU占用故障排查

    问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...

  6. 生产环境JAVA进程高CPU占用故障排查

    问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...

  7. 生产环境下JAVA进程高CPU占用故障排查---temp

    问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...

  8. 性能分析(1)- Java 进程导致 CPU 使用率升高,问题怎么定位?

    性能分析小案例系列,可以通过下面链接查看哦 ps:这些分析小案例不能保证百分比正确,是博主学习过程中的总结,仅做参考 前提 本机有一个很占用 CPU 的项目,放在了 Tomcat 下启动着 如何定位 ...

  9. VisualVM连接远程Java进程

    jstatd是一个RMI(Remove Method Invocation)的server应用,用于监控jvm的创建和结束,并且提供接口让监控工具(如VisualVM)可以远程连接到本机的jvms . ...

随机推荐

  1. Ceph源码解析:CRUSH算法

    1.简介 随着大规模分布式存储系统(PB级的数据和成百上千台存储设备)的出现.这些系统必须平衡的分布数据和负载(提高资源利用率),最大化系统的性能,并要处理系统的扩展和硬件失效.ceph设计了CRUS ...

  2. Eclipse启动时禁用不必要的验证。

    window>preferences>general>editors>text editors>Annotations,右边的Annotation type里,点选err ...

  3. DSSM 深度学习解决 NLP 问题:语义相似度计算

    https://cloud.tencent.com/developer/article/1005600

  4. 使用ERStudio创建数据表与ER图

    内容中包含 base64string 图片造成字符过多,拒绝显示

  5. 使用FreeMarker的Web Project例子

    1 创建一个名为FreemarkerDemo的Web Project 2 删除index.jsp,新建index.html,index.html中的内容为: <html> <head ...

  6. matplotlib绘制常用统计图

    常见统计图:单条折线图.多条折线图.直方图.柱状图.饼状图 #!/usr/bin/python # -*- coding: utf-8 -*- import numpy as np import ma ...

  7. Ftp上传文件

    package net.util.common; import java.io.File; import java.io.FileInputStream; import java.io.FileOut ...

  8. scrapy报错:ImportError: No module named 'win32api'

    https://github.com/mhammond/pywin32/releases 下载安装对应的版本即可.

  9. git使用 ——转

    转自:http://blog.csdn.net/jamesmf/article/details/17483787

  10. Springboot配置文件加载顺序

    使用Springboot开发的时候遇到了配置的问题,外部config里的配置文件本来没有配置https怎么启动还是https呢,原来开发中测试https在classpath路径的配置文件添加https ...