Java | 一分钟掌握JDK命令行工具 | 3 - 实战

作者:Mars酱

声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。

转载:欢迎转载,转载前先请联系我!

前言

前一篇 Java | 一分钟掌握JDK命令行工具 | 2- 分类 - 掘金 (juejin.cn) 罗列了一些JDK命令行工具,我们没有必要把所有命令行工具全部介绍,那样对于开发者来说不实用也没有任何价值,所有功能介绍,这件事情由且只能由JDK的发行方自己做。来,我们上实战的车~

实战

基本操作

既然知道了概念,我们做个基本操作。首先我们罗列出系统中有哪些正在运行的java进程:

jps

如果你的jps命令不可以用,有两种解决方案,一种是检查你的环境变量配置,比如:pathclasspath这些是不是已经配置好;另一种是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的。

最后

呵呵,一分钟也不过如此,少说多做才持久,下个章节见。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值