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守护线程内启动的非守护线程。