作者:Mars酱
声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。
转载:欢迎转载,转载前先请联系我!
前言
前一篇 Java | 一分钟掌握JDK命令行工具 | 2- 分类 - 掘金 (juejin.cn) 罗列了一些JDK命令行工具,我们没有必要把所有命令行工具全部介绍,那样对于开发者来说不实用也没有任何价值,所有功能介绍,这件事情由且只能由JDK的发行方自己做。来,我们上实战的车~
实战
基本操作
既然知道了概念,我们做个基本操作。首先我们罗列出系统中有哪些正在运行的java进程:
jps
如果你的jps
命令不可以用,有两种解决方案,一种是检查你的环境变量配置,比如:path
、classpath
这些是不是已经配置好;另一种是cd到你jdk的安装目录,进入bin文件夹,再执行jps。
以下是我的bin文件夹下的内容:
jps命令敲入之后,会看到列出了系统中运行的java进程:
如果想查看完整的进程信息,可以使用jps -l
,得到的结果会类似这样:
其中4952这个进程pid,是由jdk.jcmd/sun.tools.jps.Jps这个主类执行的。pid=58321和pid=58266这两个进程是怎么回事呢?我们使用jinfo
命令查看一下:
jinfo #java进程id#
我查看了58266这个进程,得到的信息类似这样:
逐行查看,原来是我的idea开发工具,里面罗列了很多idea这个进程的配置信息,图没截完,信息比较长还很粗。
反编译自己的代码
那么我们来写一段无限循环代码,然后对这段代码进行反编译、运行的监控和分析吧,我们拿 1 - 基础 中爷爷跟我说‘Hello World’的例子改造一下:
/**
* @author mars酱
*/
public class GranfatherTalkToMe {
public static void main(String[] args) throws InterruptedException {
while (true) {
System.out.println("Hello World");
Thread.sleep(5000);
}
}
}
爷爷跟我说‘Hello World’,然后打盹5秒,如此反复。先确保它能正确的运行:
ok,可以正常运行,那么我们不停止程序,在系统命令行使用jps -l
来查看一下:
最后一行那个6172进程就是我们编写的java代码,我们反编译一下它,使用javap
javap #class文件名#
这样,就会在命令行看到:
好了,反编译也可用。
给进程拍照
我们把GranfatherTalkToMe
运行起来,然后通过jmap
命令来生成快照,保存在桌面,使用命令:
jmap -dump:format=b,file=#保存路径##想要保存的文件名#.hprof #java进程id#
会得到类似的信息:
Heap dump file created
这行提示信息表示快照文件已经生成。
分析进程内容
jhat
可以用来通过网页查看和分析 heapdump 文件,它会在本地建立一个 HTTP/HTML 服务,我们可以打开浏览器查看分析结果:
~ /Desktop >jhat gttm.hprof
Reading from gttm.hprof...
Dump file created Sat Apr 08 14:13:42 CST 2023
Snapshot read, resolving...
Resolving 11269 objects...
Chasing references, expect 2 dots..
Eliminating duplicate references..
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
Server is ready
这个提示标示服务运行成功,我们打开浏览器,输入http://localhost:7000/
就可以看到结果。如果你的7000端口被占用,自行腾出来吧。
网页效果类似如下:
给当前任务一个快照
一些时候,我们程序可能耗费很高cpu或者内存,那我们就需要分析一下这个任务的情况了,可以使用jstack
给当前时刻进行快照。
执行命令:
jstack #java进程id#
得到类似结果(部分):
~/Desktop > jstack 9598
2023-04-08 14:40:34
Full thread dump OpenJDK 64-Bit Server VM (25.312-b07 mixed mode):
"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007f9120821800 nid=0x5107 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Service Thread" #12 daemon prio=9 os_prio=31 tid=0x00007f911f016800 nid=0x7c03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #11 daemon prio=9 os_prio=31 tid=0x00007f90d8808800 nid=0x5a03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #10 daemon prio=9 os_prio=31 tid=0x00007f90d800a000 nid=0x7e03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #9 daemon prio=9 os_prio=31 tid=0x00007f90d8009000 nid=0x5803 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #8 daemon prio=9 os_prio=31 tid=0x00007f911f810000 nid=0x5603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"JDWP Command Reader" #7 daemon prio=10 os_prio=31 tid=0x00007f9121042000 nid=0x5503 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"JDWP Event Helper Thread" #6 daemon prio=10 os_prio=31 tid=0x00007f90ff022000 nid=0x4903 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"JDWP Transport Listener: dt_socket" #5 daemon prio=10 os_prio=31 tid=0x00007f90ff021000 nid=0x4703 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007f911f80e000 nid=0x4c03 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007f911f80c800 nid=0x4103 in Object.wait() [0x00007000035e4000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000715588ee0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x0000000715588ee0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007f912081e800 nid=0x3503 in Object.wait() [0x00007000034e1000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000715586c00> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000715586c00> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"main" #1 prio=5 os_prio=31 tid=0x00007f9121008800 nid=0x1503 waiting on condition [0x00007000028bd000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.mars.GranfatherTalkToMe.main(GranfatherTalkToMe.java:10)
"VM Thread" os_prio=31 tid=0x00007f9121041000 nid=0x3303 runnable
当前线程很健康,没有问题。
jstack出来的信息,大家可能会看不懂,但是大致也就这样几种状态:
NEW
:未启动的,不会出现在Dump中;
RUNNABLE
: 在虚拟机内执行的;
BLOCKED
:受阻塞并等待监视器锁;
WATING
:无限期等待另一个线程执行特定操作;
TIMED_WATING
:有时限的等待另一个线程的特定操作;
TERMINATED
:已退出的;
如果出现死锁的情况,会直接提示DeadLock的。
最后
呵呵,一分钟也不过如此,少说多做才持久,下个章节见。
标签:lang,java,JDK,prio,31,Thread,nid,命令行,Java From: https://blog.51cto.com/marsz/6192456