17

有没有办法使用纯 Java 监控 CPU 使用率?

4

6 回答 6

10

kgiannakakis 链接的文章的评论中有一个宝石:

javasysmon

JavaSysMon 跨平台管理进程并报告有用的系统性能指标。您可以将其视为 UNIX 'top' 命令的跨平台版本,以及终止进程的能力。它以单个 JAR 文件 /..

- 适用于 Windows、Mac OS X、Linux 和 Solaris。

于 2010-01-14T07:15:58.730 回答
7

使用 jmx mbeans 怎么样?

final OperatingSystemMXBean myOsBean= 
            ManagementFactory.getOperatingSystemMXBean();
double load = myOsBean.getSystemLoadAverage();
于 2010-01-14T10:47:07.800 回答
6

可以使用 jMX bean 来计算 CPU 负载。请注意,这测量的是 Java 程序的 CPU 负载,而不是整体系统负载。(问题没有具体说明)

初始化:

    ThreadMXBean newBean = ManagementFactory.getThreadMXBean();
    try
    {
        if (this.newBean.isThreadCpuTimeSupported())
            this.newBean.setThreadCpuTimeEnabled(true);
        else
            throw new AccessControlException("");
    }
    catch (AccessControlException e)
    {
        System.out.println("CPU Usage monitoring is not available!");
        System.exit(0);
    }

然后作为您的循环(假设您的应用程序使用循环,否则测量 CPU 使用率有什么意义?)使用:

    long lastTime = System.nanoTime();
    long lastThreadTime = newBean.getCurrentThreadCpuTime();

    while (true)
    {
        // Do something that takes at least 10ms (on windows)
        try
        {
            int j = 0;
            for (int i = 0; i < 20000000; i++)
                j = (j + i) * j / 2;
            Thread.sleep(100);
        }
        catch (InterruptedException e)
        {
        }

        // Calculate coarse CPU usage:
        long time = System.nanoTime();
        long threadTime = newBean.getCurrentThreadCpuTime();
        double load = (threadTime - lastThreadTime) / (double)(time - lastTime);
        System.out.println((float)load);

        // For next iteration.
        lastTime = time;
        lastThreadTime = threadTime;
    }

您需要使用双精度,因为 long 不适合浮点数(尽管它可能工作 99.9999999999999999% 的时间)

如果您正在做的“某事”花费的时间少于大约 1.6 毫秒(Windows),那么返回的值甚至根本不会增加,您将永远错误地测量 0% CPU。

因为getCurrentThreadCpuTime非常不准确(延迟小于 100 毫秒),所以平滑它有很大帮助:

    long lastTime = System.nanoTime();
    long lastThreadTime = newBean.getCurrentThreadCpuTime();

    float smoothLoad = 0;
    while (true)
    {
        // Do something that takes at least 10ms (on windows)
        try
        {
            int j = 0;
            for (int i = 0; i < 2000000; i++)
                j = (j + i) * j / 2;
            Thread.sleep(10);
        }
        catch (InterruptedException e)
        {
        }

        // Calculate coarse CPU usage:
        long time = System.nanoTime();
        long threadTime = newBean.getCurrentThreadCpuTime();
        double load = (threadTime - lastThreadTime) / (double)(time - lastTime);
        // Smooth it.
        smoothLoad += (load - smoothLoad) * 0.1; // damping factor, lower means less responsive, 1 means no smoothing.
        System.out.println(smoothLoad);

        // For next iteration.
        lastTime = time;
        lastThreadTime = threadTime;
    }
于 2013-02-05T17:04:05.813 回答
1

使用纯 Java 是不可能的。有关一些想法,请参阅本文

于 2010-01-14T05:55:06.340 回答
1

也许如果卡住了,您可能会通过在后台线程中运行间歇性 bogomips 计算器并对其结果进行平滑和规范化来“感知”cpu 可用性。...值得一试不:?

于 2010-01-14T06:11:06.460 回答
0

如果您使用的是 linux - 只需使用jconsole- 您将获得 java 内存管理的所有轨迹

于 2013-11-06T07:02:24.377 回答