获取Java

时间:2015-04-28 22:57:41

标签: java benchmarking cpu-usage

我有一个关于获取给定JNI块的CPU利用率的问题。我在底层的C ++ JNI本机方法中进行了一些密集的CPU计算。我正在优化这个计算,并希望根据不同的输入进行基准测试。

我需要一些关于如何衡量这一点的指导。我到目前为止考虑的替代方案是

  • 使用JMX ThreadMXBean来测量调用JNI方法调用的当前线程的系统CPU使用率。但是,我不确定JNI代码是否在调用线程上下文中执行。当线程产生更多线程时会发生什么?

  • 使用JMX OperatingSystemMXBean获取整个JVM的CPU使用率。理想情况下,这不是我想要的,因为JVM中可能存在可能调整基准测试的并行执行。

  • 使用getrusage(..)进行外部测量。我想知道的是,它与使用OperatingSystemMXBean有什么不同。

2 个答案:

答案 0 :(得分:5)

您可以使用ThreadMXBean从所有正在运行的线程获取cpu使用情况统计信息。在下面的示例中,计算CPU usage per thread

private int sampleTime = 10000;
private ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
private RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
private OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
private Map<Long, Long> threadInitialCPU = new HashMap<Long, Long>();
private Map<Long, Float> threadCPUUsage = new HashMap<Long, Float>();
private long initialUptime = runtimeMxBean.getUptime();

ThreadInfo[] threadInfos = threadMxBean.dumpAllThreads(false, false);
for (ThreadInfo info : threadInfos) {
    threadInitialCPU.put(info.getThreadId(), threadMxBean.getThreadCpuTime(info.getThreadId()));
}

try {Thread.sleep(sampleTime);} catch (InterruptedException e) {}

long upTime = runtimeMxBean.getUptime();

Map<Long, Long> threadCurrentCPU = new HashMap<Long, Long>();
ThreadInfo[] threadInfos = threadMxBean.dumpAllThreads(false, false);
for (ThreadInfo info : threadInfos) {
    threadCurrentCPU.put(info.getThreadId(), threadMxBean.getThreadCpuTime(info.getThreadId()));
}

// CPU over all processes
//int nrCPUs = osMxBean.getAvailableProcessors();
// total CPU: CPU % can be more than 100% (devided over multiple cpus)
long nrCPUs = 1;
// elapsedTime is in ms.
long elapsedTime = (upTime - initialUptime);
for (ThreadInfo info : threadInfos) {
    // elapsedCpu is in ns
    Long initialCPU = threadInitialCPU.get(info.getThreadId());
    if (initialCPU != null) {
        long elapsedCpu = threadCurrentCPU.get(info.getThreadId()) - initialCPU;
        float cpuUsage = elapsedCpu / (elapsedTime * 1000000F * nrCPUs);
        threadCPUUsage.put(info.getThreadId(), cpuUsage);
    }
}

// threadCPUUsage contains cpu % per thread
System.out.println(threadCPUUsage);
// You can use osMxBean.getThreadInfo(theadId) to get information on every thread reported in threadCPUUsage and analyze the most CPU intentive threads

答案 1 :(得分:1)

在Linux上,此方法可以帮助您:

  • 运行kill -3 <pid of Java process>以获取线程转储。线程转储将添加标准输出。
  • 打开转储并搜索您感兴趣的主题。(您可以使用类名进行搜索)
  • 获取线程PID(以十六进制表示)并将其转换为十进制。
  • 运行top命令。
  • Shift-H启用主题视图
  • 使用您在上面获得的十进制值标识线程。 你可以在那里看到你的线程的cpu / memory使用情况。