问题 测量JVM的CPU使用情况:java代码


有没有办法测量JVM的CPU使用率(一旦启动java应用程序)跨平台(windows + unix + mac)? 我使用过Jconsole,但我需要的是一个执行此操作的java代码,而不是一个可以监视CPU利用率的工具。 我试过了

ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage()

使用JMX,但它没有帮助,因为我需要的是JVM的特定CPU使用率(比如当我启动服务器时),而不是系统负载平均值。


4494
2018-05-06 06:18


起源



答案:


你应该看一下 ThreadMXBean.getCurrentCPUTime() Thread MBean中的方法。

线程CPU时间

一个Java虚拟机   实施可能支持测量   当前线程的CPU时间,   任何线程,或没有线程。

还有JTOP示例应用程序是JDK的一部分 jdk\demo\management\JTop\src\JTop.java 要么 这里。看一下:

/**
 * Get the thread list with CPU consumption and the ThreadInfo for each thread
 * sorted by the CPU time.
 */
private List<Map.Entry<Long, ThreadInfo>> getThreadList()

8
2018-05-06 06:32



嗨,有没有办法使用ThreadMXBean.getCurrentCPUTime()方法获取JVM的cpu使用率(以百分比表示)? - nadh
您必须计算所有线程的CPU时间总和才能获得总CPU时间。我认为总和可能有点偏差,因为你不能原子地查询所有线程的CPU时间。 - Thomas Jung


答案:


你应该看一下 ThreadMXBean.getCurrentCPUTime() Thread MBean中的方法。

线程CPU时间

一个Java虚拟机   实施可能支持测量   当前线程的CPU时间,   任何线程,或没有线程。

还有JTOP示例应用程序是JDK的一部分 jdk\demo\management\JTop\src\JTop.java 要么 这里。看一下:

/**
 * Get the thread list with CPU consumption and the ThreadInfo for each thread
 * sorted by the CPU time.
 */
private List<Map.Entry<Long, ThreadInfo>> getThreadList()

8
2018-05-06 06:32



嗨,有没有办法使用ThreadMXBean.getCurrentCPUTime()方法获取JVM的cpu使用率(以百分比表示)? - nadh
您必须计算所有线程的CPU时间总和才能获得总CPU时间。我认为总和可能有点偏差,因为你不能原子地查询所有线程的CPU时间。 - Thomas Jung


Java本身不提供此功能。有几个开源API可用于衡量CPU使用率。
我建议 Sigar API。除CPU使用外,您还可以获得更多其他功能,如内存使用,系统正常运行时间等。


2
2018-05-06 06:23



这是不正确的,因为Java 1.5,当引入ThreadMXBean.getCurrentCPUTime()时,请参阅@ thomas-jung的回答。但Sigar确实有一些有趣的功能。 - Ed Griebel
SIGAR还会破坏你的JVM并使一切崩溃。即使它是间歇性的,我也不认为你能负担得起生产。 - AKS


这里

    com.sun.management.OperatingSystemMXBean operatingSystemMXBean = 
         (com.sun.management.OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
    long prevUpTime = runtimeMXBean.getUptime();
    long prevProcessCpuTime = operatingSystemMXBean.getProcessCpuTime();
    double cpuUsage;
    try 
    {
        Thread.sleep(500);
    } 
    catch (Exception ignored) { }

    operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    long upTime = runtimeMXBean.getUptime();
    long processCpuTime = operatingSystemMXBean.getProcessCpuTime();
    long elapsedCpu = processCpuTime - prevProcessCpuTime;
    long elapsedTime = upTime - prevUpTime;

    cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * availableProcessors));
    System.out.println("Java CPU: " + cpuUsage);

2
2018-03-31 18:49



我试过这个,但它似乎没有给出准确的值。与我在jconsole中看到的相比,当jconsole上的cpu使用率已经达到99%时,计算结果为65%。任何Java替代品? - Andy Dufresne


使用纯Java无法以编程方式查询CPU使用情况。根本就没有API。建议的替代方案可以使用 Runtime.exec() 确定JVM的进程ID(PID),调用外部的,特定于平台的命令,如ps,并解析其输出的感兴趣的PID。

看到这个链接


1
2018-05-06 06:23



这是不正确的,因为Java 1.5,当引入ThreadMXBean.getCurrentCPUTime()时,请参阅@ Thomas-jung的回答。此外,链接的文章来自2002年。 - Ed Griebel


在任何给定的时刻,线程正在运行(100%的核心)或不运行(0%)。 中间没有。 您需要的是线程运行状态的一系列短期快照,并对其进行平均。


1
2018-05-06 16:08



你能详细说明一下吗?您是否需要考虑被阻止或处于timed_waiting状态的线程?我看到timed_waiting线程有时会占用cpu周期。我的要求是当cpu使用率超过阈值时触发jvm以获取更多的线程转储,以便我们可以调查问题。 - Andy Dufresne


也许 这个 或类似的图书馆可以帮助你。


1
2018-05-06 08:06