【发布时间】:2011-10-21 18:00:20
【问题描述】:
我创建的用于将纳秒 CPU 时间使用率(通过 JMX 获得)转换为 100% 百分比的 Java 算法存在问题。该算法似乎给出了大于 100% 的数字,我认为这是由于多个可用处理器造成的,尽管代码应该对此进行排序。该算法可以在下面看到。 cpuTimeDiffNS 是以纳秒为单位使用的 CPU 时间量,而 periodMS 是采样周期。
public static final double getCPUPerc(long cpuTimeDiffNS, long periodMS) {
if (periodMS == 0) return 0;
double cpuTimeDiffMS = cpuTimeDiffNS / 1000000d;
int procs = Runtime.getRuntime().availableProcessors();
long availableTime = periodMS * procs;
double perc = cpuTimeDiffMS / availableTime;
return perc * 100d;
}
以下是数据采集的一些示例:
0
87.5
133.8288232
160.8231707
197.7896341
209.6036585
248.822774
274.3902439
267.9115854
271.3414634
277.1067759
283.1554878
272.1036585
279.4000734
283.9176829
283.5365854
275.9146341
282.4578033
278.9634146
261.0536937
254.6071775
286.662182
278.9634146
276.7245597
288.4908537
281.6933708
286.9664634
279.7822896
276.2957317
280.4878049
275.5335366
271.7557485
280.8689024
287.2689689
281.6933708
267.5097276
273.2469512
286.1735835
289.6341463
296.875
279.4000734
289.2530488
282.8400196
288.4908537
287.4266145
288.1097561
286.5853659
288.9554795
238.1207192
288.4908537
288.7063531
290.3963415
286.662182
277.4390244
290.4843444
281.6310976
271.7557485
272.8658537
283.2222358
250.7621951
编辑:根据要求,输入收集功能(你可以忽略这个):
// returns CPU time in NS for a thread group (recursively)
public static long getCPUTime(ThreadGroup tg) {
synchronized (TGLOCK) {
int size;
do {
size = tg.enumerate(tgThreads, true);
if (size <= tgThreads.length) continue;
tgThreads = new Thread[size];
} while (size > tgThreads.length);
long totalTime = 0;
for (int i = 0; i < size; i++) {
totalTime += getCPUTime(tgThreads[i]);
}
return totalTime;
}
}
public static long getCPUTime(Thread t) {
return threadMXBean.getThreadCpuTime(t.getId());
}
public static ThreadGroup getRootThreadGroup() {
// Find the root thread group
ThreadGroup root = Thread.currentThread().getThreadGroup().getParent();
while (root.getParent() != null) {
root = root.getParent();
}
return root;
}
和输入(同样,你可以忽略这个):
simCPUTimeNS = getCPUTime(kks.getSimThreadGroup());
appsCPUTimeNS = getCPUTime(kks.getAppThreadGroup());
lwjns3CPUTimeNS = getCPUTime(kks.getKKSThreadGroup());
simCoreCPUTimeNS = getCPUTime(kks.getSimThread());
totalCPUTimeNS = getCPUTime(getRootThreadGroup());
simCPUTimeNSDiff = simCPUTimeNS - lastSimCPUTimeNS;
appsCPUTimeNSDiff = appsCPUTimeNS - lastAppsCPUTimeNS;
lwjns3CPUTimeNSDiff = lwjns3CPUTimeNS - lastLwjns3CPUTimeNS;
simCoreCPUTimeNSDiff = simCoreCPUTimeNS - lastSimCoreCPUTimeNS;
totalCPUTimeNSDiff = totalCPUTimeNS - lastTotalCPUTimeNS;
lastSimCPUTimeNS = simCPUTimeNS;
lastAppsCPUTimeNS = appsCPUTimeNS;
lastLwjns3CPUTimeNS = lwjns3CPUTimeNS;
lastSimCoreCPUTimeNS = simCoreCPUTimeNS;
lastTotalCPUTimeNS = totalCPUTimeNS;
simCPUPerc = getCPUPerc(simCPUTimeNSDiff, currDiffMS);
appsCPUPerc = getCPUPerc(appsCPUTimeNSDiff, currDiffMS);
lwjns3CPUPerc = getCPUPerc(lwjns3CPUTimeNSDiff, currDiffMS);
simCoreCPUPerc = getCPUPerc(simCoreCPUTimeNSDiff, currDiffMS);
totalCPUPerc = getCPUPerc(totalCPUTimeNSDiff, currDiffMS);
为任何帮助干杯,我相信答案是显而易见的 ;)
克里斯
【问题讨论】:
-
希望这篇文章能更好地帮助到你:stackoverflow.com/questions/47177/…
-
您使用什么 JMX 调用和计算来获取
cpuTimeDiffNS? -
通常当我遇到这样的问题时,我会让它发出你正在计算的每个中间值。例如,您的输入是否符合您的期望? cpuTimeDiffMS 计算是否正确?过程?有空时间? perc的第一个化身?还是只有关闭的返回值?
-
我的回答对你有帮助吗@Chris?如果是,请接受。
标签: java algorithm debugging cpu-usage sampling