最消耗CPU的java线程?

当我们运行程序的时候,如果导致CPU大量被消耗,可能是我们的Java程序出现了问题,就需要定位到可能消耗大量CPU的线程,如何去做呢?

例如运行下面的程序


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BusyThread {
    public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            br.readLine();
            createBusyThread();
            br.readLine();
            Object o = new Object();
            createLockThread(o);
            createDeadLoc();
            
    }

    public static void createBusyThread() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true)
                    ;
            }
        }, "busyThreadName");
        t.start();
    }

    public static void createLockThread(final Object lock) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    try {
                        lock.wait();
                    }catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"lockThreadName");
        t.start();
    }
    public static void createDeadLoc() {
        Object a = new Object();
        Object b = new Object();
        
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (a) {
                    try {
                        Thread.sleep(3000);
                        synchronized (b) {
                            
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"t1");
        
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (b) {
                    try {
                        Thread.sleep(3000);
                        synchronized (a) {
                            
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"t2");
        t1.start();
        t2.start();
    }
}

1. 获取运行程序的进程id

jps -l
或者
ps -ef | grep BusyThread(运行程序类名)

ethan@ubuntu:~$ ps -ef | grep BusyThread
ethan      4688   1928  0 01:28 ?        00:00:14 /opt/sublime_text/sublime_text BusyThread.java
ethan      5728   5648  0 02:09 pts/4    00:00:00 java BusyThread
ethan      5789   5745  0 02:10 pts/6    00:00:00 grep --color=auto BusyThread

得到应用程序进程 id 为 5728

2. 获取对应进程下最消耗CPU 的线程 id

top -Hp 5728

top - 02:14:44 up  2:39,  1 user,  load average: 0.00, 0.12, 0.36
Threads:  14 total,   1 running,  13 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.3 us,  0.7 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  6057032 total,  3926028 free,  1285200 used,   845804 buff/cache
KiB Swap:  4191228 total,  4191228 free,        0 used.  4408076 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                   
  5840 ethan     20   0 3419616  27176  15840 R 94.7  0.4   0:03.97 java                                                      
  5737 ethan     20   0 3419616  27176  15840 S  0.3  0.4   0:00.34 java                                                      
  5728 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5729 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.06 java                                                      
  5730 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.01 java                                                      
  5731 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5732 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5733 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5734 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5735 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5736 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5841 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5842 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java                                                      
  5843 ethan     20   0 3419616  27176  15840 S  0.0  0.4   0:00.00 java 

得到最消耗CPU的 线程 id 为 5840

3. 计算对应线程 id 的 十六进制

printf "%x\n" 5840

ethan@ubuntu:~$ printf "%x\n" 5840
16d0

4. 分析对应线程的堆栈信息

jstack 5728 | grep 16d0

ethan@ubuntu:~$ jstack 5728 | grep 16d0
"busyThreadName" #8 prio=5 os_prio=0 tid=0x00007fa5f80cb000 nid=0x16d0 runnable [0x00007fa5e346c000]

表明当前最占据CPU 的线程名为: busyThreadName ,当前处于 Runnable 状态

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 4,334评论 0 23
  • 一. 操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式: 向下管理硬件,向上提供接口.操作系统进行...
    月亮是我踢弯得阅读 6,188评论 3 28
  • 转自:彻底了解android中的内部存储与外部存储 我们先来考虑这样一个问题: 打开手机设置,选择应用管理,选择任...
    玉圣阅读 473评论 0 1
  • 1、邹市明确诊眼眶骨折并患白内障,要完全恢复非常困难,一份邹市明出场费仅5500美金的合约截屏被曝光,网友戏称挨一...
    顺遂小Q阅读 86评论 0 0
  • 昨小组会让我对白板上那些字的理解又深一层了,“信念—行动—成果”,还有”目标——情绪张力、创造性张力”、”领袖三大...
    霞DENTIST阅读 339评论 0 0

友情链接更多精彩内容