利用JMX统计远程JAVA进程的CPU和Memory
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了,类依赖图如下:

示例代码:
- /*
- * host: 远程机器的ip地址
- * port: 远程java进程运行的jmxremote端口
- */
- JMXServiceURL serviceURL = new JMXServiceURL( host,port );
- JMXConnector conn = JMXConnectorFactory.connect(serviceURL);
- MBeanServerConnection mbs=conn.getMBeanServerConnection();
- //获取远程memorymxbean
- MemoryMXBean memBean=ManagementFactory.newPlatformMXBeanProxy
- (mbs,ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
- //获取远程opretingsystemmxbean
- com.sun.management.OperatingSystemMXBean opMXbean =
- ManagementFactory.newPlatformMXBeanProxy(mbs,
- ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);
然后,采集memory的数据就比较简单了,直接调用API获取:
- /** Collect data every 5 seconds */
- try {
- TimeUnit.SECONDS.sleep(5);
- } catch (InterruptedException e) {
- logger.error("InterruptedException occurred while MemoryCollector sleeping...");
- }
- MemoryUsage heap = memBean
- etHeapMemoryUsage();
- MemoryUsage nonHeap = memBean
- etNonHeapMemoryUsage();
- long heapSizeUsed = heap.getUsed();//堆使用的大小
- long nonHeapSizeUsed = nonHeap.getUsed();
- long heapCommitedSize = heap.getCommitted();
- long nonHeapCommitedSize = nonHeap.getCommitted();
采集CPU利用率需要自己计算一下,因为API只提供了获取cpu的使用时间,我得在两次系统时间间隔内获取两次CPU的使用时间,得到在该时间间隔内cpu使用的时间,相除即得到CPU的使用率,当然误差肯定存在。
- Long start = System.currentTimeMillis();
- long startT = opMXbean.getProcessCpuTime();
- /** Collect data every 5 seconds */
- try {
- TimeUnit.SECONDS.sleep(5);
- } catch (InterruptedException e) {
- logger.error("InterruptedException occurred while MemoryCollector sleeping...");
- }
- Long end = System.currentTimeMillis();
- long endT = opMXbean.getProcessCpuTime();
- //end - start 即为当前采集的时间单元,单位ms
- //endT - startT 为当前时间单元内cpu使用的时间,单位为ns
- //所以:double ratio = (entT-startT)/1000000.0/(end-start)/opMXbean.getAvailableProcessors()
核心代码就是这些了,当然,具体使用的话应该用单独的线程分别取cpu、memory数据,读取的数据需要写文件或者画图,监控时间长的话还要定时的将这些数据刷到磁盘文件或数据库中,等,这些都是题外话了。这边我写到excel中,然后在excel中图形展示,远程监控的程序不方便展示,仅仅来监控一段模拟cpu正弦曲线的程序
,来看看我监控到的数据(图形)是否和预期一致,并与jconsole采到的有何差异:
- public class SinCpu {
- public static final double TIME = 1000;
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) throws InterruptedException {
- new Thread(new SinTask()).start();
- }
- static class SinTask implements Runnable{
- @Override
- public void run() {
- double x = 0;
- double y = 0;
- while (true) {
- y = (Math.sin(x) + 1) * TIME / 2;
- doSomeSimpleWork(y);
- x += 0.1;
- try {
- Thread.sleep((long) (TIME - y));
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- private void doSomeSimpleWork(double y) {
- long startTime = System.currentTimeMillis();
- while ((System.currentTimeMillis() - startTime) < y) {
- }
- }
- }
- }
监控结果基本和预期一样,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的更多相关文章
- 利用JMX统计远程JAVA进程的CPU和Memory---jVM managerment API
从JAVA 5开始,JDK提供了一些JVM检测的API,这就是有名的java.lang.management 包,包里提供了许多MXBean的接口类,可以很方便的获取到JVM的内存.GC.线程.锁.c ...
- JVM探秘:VisualVM监控远程Java进程
VisualVM在Java 8中是JDK自带的一个图形化工具,项目主页 VisualVM,在后续版本中可能会从JDK移除. VisualVM可以监控Java进程的CPU与内存占用情况,可以监控Java ...
- JVM调优之Java进程消耗CPU过高
JVM调优之Java进程消耗CPU过高 查找问题思路 1.查看cpu使用率,发现有线程cpu占用率很高 tops 咱们拿18092线程举例示范 2.查询pid对应的进程 ps -ef|grep 18 ...
- Java进程占用CPU资源过多分析
问题描述: 生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析: 1,程序属于CPU密集型,和开发沟通 ...
- 生产环境下JAVA进程高CPU占用故障排查
问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...
- 生产环境JAVA进程高CPU占用故障排查
问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...
- 生产环境下JAVA进程高CPU占用故障排查---temp
问题描述:生产环境下的某台tomcat7服务器,在刚发布时的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高. 问题分析:1,程序属于CPU密集型,和开发沟通过, ...
- 性能分析(1)- Java 进程导致 CPU 使用率升高,问题怎么定位?
性能分析小案例系列,可以通过下面链接查看哦 ps:这些分析小案例不能保证百分比正确,是博主学习过程中的总结,仅做参考 前提 本机有一个很占用 CPU 的项目,放在了 Tomcat 下启动着 如何定位 ...
- VisualVM连接远程Java进程
jstatd是一个RMI(Remove Method Invocation)的server应用,用于监控jvm的创建和结束,并且提供接口让监控工具(如VisualVM)可以远程连接到本机的jvms . ...
随机推荐
- [Java基础] java的守护线程与非守护线程
最近重新研究Java基础知识,发现以前太多知识知识略略带过了,比较说Java的线程机制,在Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) ,(PS:以 ...
- 逻辑回归Logistic Regression 之基础知识准备
0. 前言 这学期 Pattern Recognition 课程的 project 之一是手写数字识别,之二是做一个网站验证码的识别(鸭梨不小哇).面包要一口一口吃,先尝试把模式识别的经典问题—— ...
- 客户端的javascript改变了asp.net webform页面控件的值,后台代码中如何获取修改后的值。
客户端的javascript改变了asp.net webform页面控件的值,后台代码中如何获取修改后的值. 无论是什么的html控件,只要加上了runat="server" ...
- iOS: 环信的推送
原文:http://m.blog.csdn.net/article/details?id=38824551 1.先创建一个apns证书,链接如下 http://developer.easemob.co ...
- .NET MVC 验证码
.NET MVC 验证码
- vue项目构建实战基础知识:SPA理解/RESTful接口介绍/static目录配置/axios封装/打包时map文件去除
一.SPA 不是指水疗.是 single page web application 的缩写.中文翻译为 单页应用程序 或 单页Web应用,更多解释请自行搜索. 所有的前端人员都应该明白我们的页面的 u ...
- 在笛卡尔坐标系上描绘函数 y=4x^2-2/4x-3
代码: <!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type ...
- C#秘密武器之委托
在C#的世界里,委托是无处不在,尤其在.NET自己封装的框架里到处都有其身影,所以掌握委托就很有必要了!那什么是委托呢?其实委托就是一种数据类型,跟int等东东差不多,只不过在使用时要自己先去构建一个 ...
- lodash merge mergeWith使用
1.作用 递归合并来源对象的自身和继承的可枚举属性到目标对象. 2.示例 <!DOCTYPE html> <html lang="zh"> <head ...
- struts struts拦截器(过滤器)
在struts中尽量避免自定义拦截器,因为大部分需要自己定义拦截器的时候,设计思路就不对了.大部分拦截器框架都有给你定义好了.而且如果在struts中定义拦截器相当于和这个框架绑定了,假如以后要扩展或 ...