`监控java中每个线程的cpu使用情况?

Posted

技术标签:

【中文标题】`监控java中每个线程的cpu使用情况?【英文标题】:`Monitor cpu usage per thread in java? 【发布时间】:2010-10-19 20:18:13 【问题描述】:

我想问一下是否有一些简单的方法可以确定java 中每个线程的cpu usage。谢谢

【问题讨论】:

【参考方案1】:

我相信JConsole (archived link) 确实通过插件提供了这种信息

它使用ThreadMXBeangetThreadCpuTime() 函数。

类似的东西:

        long upTime = runtimeProxy.getUptime();
        List<Long> threadCpuTime = new ArrayList<Long>();
        for (int i = 0; i < threadIds.size(); i++) 
            long threadId = threadIds.get(i);
            if (threadId != -1) 
                threadCpuTime.add(threadProxy.getThreadCpuTime(threadId));
             else 
                threadCpuTime.add(0L);
            
        
        int nCPUs = osProxy.getAvailableProcessors();
        List<Float> cpuUsageList = new ArrayList<Float>();
        if (prevUpTime > 0L && upTime > prevUpTime) 
            // elapsedTime is in ms
            long elapsedTime = upTime - prevUpTime;
            for (int i = 0; i < threadIds.size(); i++) 
                // elapsedCpu is in ns
                long elapsedCpu = threadCpuTime.get(i) - prevThreadCpuTime.get(i);
                // cpuUsage could go higher than 100% because elapsedTime
                // and elapsedCpu are not fetched simultaneously. Limit to
                // 99% to avoid Chart showing a scale from 0% to 200%.
                float cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 1000000F * nCPUs));
                cpuUsageList.add(cpuUsage);
            
        

【讨论】:

请注意,您可能还想检查您正在运行的 JVM 中是否启用了 CpuTime。 'threadBean_.isThreadCpuTimeEnabled()' 将返回布尔值,如果不使用 'threadBean_.setThreadCpuTimeEnabled(true)',您可以随时设置它【参考方案2】:

通过使用java.lang.management.ThreadMXBean。如何获取 ThreadMXBean:

 ThreadMXBean tmxb = ManagementFactory.getThreadMXBean();

然后您可以使用以下命令查询特定线程的消耗量:

 long cpuTime = tmxb.getThreadCpuTime(aThreadID);

希望对你有帮助。

【讨论】:

getThreadCPUTime 与 CPU % 消耗不同 - CPUTime 告诉您线程使用 CPU 的时间,而不是在那一刻消耗了多少 CPU 资源。【参考方案3】:

Option_1:代码级别

在您的业务逻辑代码中;在开始调用 start() API 和 finally 块调用 stop() 中。这样您将获得 CPU 时间来通过当前正在运行的线程执行您的逻辑。然后记录它。 Reference.

class CPUTimer 

    private long _startTime = 0l;

    public void start ()
    
        _startTime = getCpuTimeInMillis();
    


    public long stop ()
    
        long result = (getCpuTimeInMillis() - _startTime);
        _startTime = 0l;
        return result;
    

    public boolean isRunning ()
    
        return _startTime != 0l;
    

    /** thread CPU time in milliseconds. */
    private long getCpuTimeInMillis ()
    
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        return bean.isCurrentThreadCpuTimeSupported() ? bean.getCurrentThreadCpuTime()/1000000: 0L;
    

Option_2:使用插件的监视器级别(不支持 jvisualvm 的 AIX IBM 机器)

如果您认为现在添加代码是延迟,那么您可以选择支持插件的 JConsole。我关注了this 文章。从那篇文章中下载 topthreads jar 并运行 ./jconsole -pluginpath topthreads-1.1.jar

Option_3:使用 TOP (shift H) + JSTACK(支持 'Shif+H' 的 Unix 机器)监控级别

按照this 教程,top 命令将提供查找*** CPU 线程 (nid) 的选项。检查 jstack 输出文件中的 nid。

【讨论】:

【参考方案4】:

试试“TopThreads”JConsole 插件。见http://lsd.luminis.nl/top-threads-plugin-for-jconsole/

【讨论】:

链接已失效,arnhem.luminis.eu/new_version_topthreads_jconsole_plugin【参考方案5】:

虽然这取决于平台,但我相信您正在寻找的是 ThreadMXBean:http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/ThreadMXBean.html。例如,您可以使用 getThreadUserTime 方法来获取您需要的内容。要检查您的平台是否支持 CPU 测量,您可以调用 isThreadCpuTimeSupported() 。

【讨论】:

【参考方案6】:

事实上,ThreadMXBean 对象提供了您需要的功能(但它可能不会在所有虚拟机上实现)。

在 JDK 1.5 中有一个演示程序可以完全满足您的需要。它在文件夹 demo/management 中,名为 JTop.java

不幸的是,Java6 中没有。也许你可以用google找到或下载JDK5。

【讨论】:

以上是关于`监控java中每个线程的cpu使用情况?的主要内容,如果未能解决你的问题,请参考以下文章

Java编程思想-并发

根据 CPU 和 RAM 使用情况调整线程池的 Java Executor

集群监控

错误记录应用运行 CPU 占用率达到 90% ( 使用 CPU Profiler 监控应用运行情况 )

如何定位cpu占用率高的java线程

启用超线程时如何在 GRAFANA 中获取 CPU 的聚合使用情况