如何找到占用cpu最高的java线程?tomcat所在线程是守护线程吗?如何在linux中断一个Java进程中的线程,如何让一个守护线程不被结束

1. 如何找到占用cpu最高的java线程

1.1 过程

1,使用命令top -p ,显示你的java进程的内存情况,pid是你的java进程号,比如123
2,按H,获取每个线程的内存情况 c显示启动命令
3,找到内存和cpu占用最高的线程pid,比如15248
4,执行 printf 0x%x 15248 得到 0x3b90 ,此为线程id的十六进制
5,执行 jstack 123|grep -A 10 3b90,得到线程堆栈信息中3b90这个线程所在行的后面10行
6,查看对应的堆栈信息找出可能存在问题的代码

1.2 示例

1.2.1 ps-ef|grep xxx 查询Java实例进程
[root@iZ2zei0nwllapkwklisoncZ data]# ps -ef|grep netty
root      8794  7716  0 11:02 pts/2    00:00:04 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dependencies.jar Thead4Test
1.2.2 top -p 8794 H c查询进程的子线程状态
 PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                 
 8794 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.00 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8795 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.05 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8796 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.81 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8797 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.00 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8798 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.00 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8799 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.00 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8800 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.24 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8801 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.09 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8802 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.00 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8803 root      20   0 2464424  41244  12328 S  0.0  2.2   0:01.57 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8804 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.54 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8805 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.38 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+  8806 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.42 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
 8807 root      20   0 2464424  41244  12328 S  0.0  2.2   0:00.37 java -cp target/netty_test-0.0.1-SNAPSHOT-jar-with-dep+ 
1.2.3 printf 0x%x 8795查看16进制线程号
[root@iZ2zei0nwllapkwklisoncZ data]# printf 0x%x 8795
0x225b[root@iZ2zei0nwllapkwklisoncZ data]# 
1.2.4 jstack 8794 |grep -A 10 225b 查询堆栈信息
0x225b[root@iZ2zei0nwllapkwklisoncZ data]# jstack 8794 |grep -A 10 225b
"DestroyJavaVM" #12 prio=5 os_prio=0 tid=0x00007f0324008800 nid=0x225b waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"线程4" #11 prio=5 os_prio=0 tid=0x00007f0324107800 nid=0x2267 waiting on condition [0x00007f0314cfb000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at Thead4Test$SubThread.run(Thead4Test.java:27)

"线程3" #10 prio=5 os_prio=0 tid=0x00007f0324105800 nid=0x2266 waiting on condition [0x00007f0314dfc000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
[root@iZ2zei0nwllapkwklisoncZ data]# 

2. 如何在linux中断一个Java进程中的线程

接上个例子,我们获得某个Java进程所有的线程之后。
kill -9 nid或者kill -2 nid。可不可以杀死线程?
结论是这样整个进程都会结束。
线程结束的正确方法是让其自动结束,我们可以设置标志。还有一种线程结束的情况是自己是守护线程,没有其他用户线程的时候自己会自动结束。

3. 如何让一个守护线程不被结束?

如果某个线程是守护线程,如果不想被关闭,则这个守护线程如果自己再启动一个用户线程就可以了。当然这样其他的守护线程也不会被关掉。
例子:

/**
 *  后台线程是否会撤销?
 */
public class ThreadDeamoTest {
    public static void main(String args[]) {

        Thread t = new DeamoThread();
        t.setDaemon(true);
        t.start();
        LogCore.BASE.info("count={}, all={}", Thread.activeCount(),
                    Util.prettyJsonStr(Thread.getAllStackTraces().keySet()));
    }

    private static class DeamoThread extends Thread {
        public DeamoThread() {
            this.setName("test deamo");
        }

        @Override
        public void run() {
            System.out.println("sttart");
            new NotDeamoThread().start();
            while (true) {
                ThreadUtil.sleep(10000);
                System.out.println("hei"+this.isDaemon());
            }
        }
    }

    private static class NotDeamoThread extends Thread {
        public NotDeamoThread() {
            this.setName("test not deamo");
            this.setDaemon(false);
        }

        @Override
        public void run() {
            System.out.println("sttart");
            while (true) {
                ThreadUtil.sleep(10000);
                System.out.println("no demo hei"+this.isDaemon());
            }
        }
    }
}

4. tomcat所在线程是守护线程吗

Q:springboot的内置tomcat所在线程是守护线程吗?
A:是的
这里写图片描述
点进去
这里写图片描述
使用jvisualvm观察
启动前
这里写图片描述
启动中,其中线程container-0就是Tomcat守护线程内启动的非守护线程。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值