【发布时间】:2011-09-29 16:23:22
【问题描述】:
有没有办法使用纯 Java 监控 CPU 使用率?
【问题讨论】:
有没有办法使用纯 Java 监控 CPU 使用率?
【问题讨论】:
kgiannakakis 链接的文章中的 cmets 中有一颗宝石:
JavaSysMon 管理进程和 报告有用的系统性能 指标跨平台。你可以想 它作为一个跨平台版本 UNIX 的“top”命令,以及 杀死进程的能力。它进来 单个 JAR 文件的形式 /..
-适用于 Windows、Mac OS X、Linux 和 Solaris。
【讨论】:
使用 jmx mbeans 怎么样?
final OperatingSystemMXBean myOsBean=
ManagementFactory.getOperatingSystemMXBean();
double load = myOsBean.getSystemLoadAverage();
【讨论】:
您可以使用 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;
}
【讨论】:
这在纯 Java 中是不可能的。有关一些想法,请参阅此article。
【讨论】:
如果卡住了,您可能会通过在后台线程中运行间歇性 bogomips 计算器并对其结果进行平滑和规范化来“感知”cpu 可用性。 ...值得一试不:?
【讨论】:
System.nanoTime())。在时间间隔内,性能仍然会有相当大的波动。
如果您使用的是 linux - 只需使用 jconsole - 您将获得 java 内存管理的所有轨迹
【讨论】: