前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >不可不知的 7 个 JDK 命令

不可不知的 7 个 JDK 命令

原创
作者头像
武培轩
修改于 2020-06-08 03:11:49
修改于 2020-06-08 03:11:49
4940
举报
文章被收录于专栏:武培轩的专栏武培轩的专栏

这篇文章主要来介绍下 JDK 内置的命令,话不多说,让我们开始吧!

javap

使用 javap 可以查看 Java 字节码反编译的源文件,javap 的命令格式如下:

javap
javap

下面来演示下用 javap -c 对代码进行反编译,首先写个 HelloWorld 类,如下:

代码语言:txt
AI代码解释
复制
public class HelloWorld {
    public static void main(String []args) {
       System.out.println("Hello World");
    }
}

接着使用 javap -c HelloWorld.class 就可以反编译得到如下结果:

代码语言:txt
AI代码解释
复制
Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hello World
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}

jps

jps 是用来查询当前所有进程 pid 的,命令的用法如下图所示:

jps
jps

执行 jps 可以获取本机 Java 程序的 pid,运行结果如下:

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jps
8825 spring-boot-0.0.1-SNAPSHOT.jar

使用 jps -mlvV 可以获取到这个进程的 pid、jar 包的名字以及 JVM 参数等。

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jps -mlvV
8825 /root/spring-boot-0.0.1-SNAPSHOT.jar --server.port=8090 --logging.file=/root/log/spring-boot.log -Xmx1024m -Xms1024m

jstat

jstat 主要用于监控 JVM,主要是 GC 信息,在性能优化的时候经常用到,命令内容如下所示:

jstat
jstat

比如,上面我们通过 jps 查到的进程号 8825,我们使用 jstat -gc 8825 来查看该进程的 GC 信息:

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jstat -gc 8825
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
65536.0 69120.0  0.0   160.0  10425344.0 1036247.8 21135360.0 19489859.7 84608.0 81123.8 9600.0 8834.1  99517 2070.459   0      0.000 2070.459

其中 S0C 表示当前 Survivor0 的容量,S1C 表示当前 Survivor1 的容量,S0U 表示当前 Survivor0 的利用率,S1U 表示当前 Survivor1 的利用率,EC 表示 Eden 的容量,EU 表示 Eden 的利用率,OC 表示老年代的容量,OU 表示老年代的利用率,MC 表示 Metaspace 的容量,MU 表示 Metaspace 的利用率,CCSC 表示类指针压缩空间容量,CCSU 表示使用的类指针压缩空间,YGC 表示新生代 GC 的次数,YGCT 表示新生代 GC 的时间,FGC 表示 Full Gc 的次数,FGCT 表示 Full GC 的时间,GCT 表示 GC 总时间。

每个对象都有一个指向它自身类的指针,_klass: 指向类的 4 字节指针,64 位平台上 _klass: 指向类的 8 字节的指针,为了节约这些空间,引入了类指针压缩空间。

jcmd

jcmd 可以查看 JVM 信息,常用的命令内容如下:

jcmd
jcmd

先使用 jcmd 8825 help 来查看都支持什么命令:

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jcmd 8825 help
8825:
The following commands are available:
JFR.stop
JFR.start
JFR.dump
JFR.check
VM.native_memory
VM.check_commercial_features
VM.unlock_commercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
VM.classloader_stats
GC.rotate_log
Thread.print
GC.class_stats
GC.class_histogram
GC.heap_dump
GC.finalizer_info
GC.heap_info
GC.run_finalization
GC.run
VM.uptime
VM.dynlibs
VM.flags
VM.system_properties
VM.command_line
VM.version
help

下面我就选一个参数给大家举个例子,比如打印堆的信息,使用 jcmd 8825 GC.heap_dump 命令:

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jcmd 8825 GC.heap_info
8825:
 PSYoungGen      total 628736K, used 41772K [0x0000000715a00000, 0x0000000746480000, 0x00000007c0000000)
  eden space 609792K, 4% used [0x0000000715a00000,0x00000007173d5478,0x000000073ad80000)
  from space 18944K, 80% used [0x000000073ad80000,0x000000073bc75e68,0x000000073c000000)
  to   space 19968K, 0% used [0x0000000745100000,0x0000000745100000,0x0000000746480000)
 ParOldGen       total 250880K, used 21756K [0x00000005c0e00000, 0x00000005d0300000, 0x0000000715a00000)
  object space 250880K, 8% used [0x00000005c0e00000,0x00000005c233f160,0x00000005d0300000)
 Metaspace       used 44797K, capacity 45562K, committed 45824K, reserved 1089536K
  class space    used 5669K, capacity 5832K, committed 5888K, reserved 1048576K

可以看出可以获取新生代、老年代、元空间、Eden、From Survivor 以及 To Survivor 的大小和占比。

jmap

jmap 打印出 Java 进程内存中 Object 的情况,或者将 JVM 中的堆以二进制输出成文本,命令内容如下:

jmap
jmap

使用 jmap -heap 8825 查看当前堆的使用信息:

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jmap -heap 8825
Attaching to process ID 8825, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.201-b09

using thread-local object allocation.
Parallel GC with 10 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 8575254528 (8178.0MB)
   NewSize                  = 178782208 (170.5MB)
   MaxNewSize               = 2858418176 (2726.0MB)
   OldSize                  = 358088704 (341.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 624427008 (595.5MB)
   used     = 32083672 (30.597373962402344MB)
   free     = 592343336 (564.9026260375977MB)
   5.138098062536078% used
From Space:
   capacity = 19398656 (18.5MB)
   used     = 15687272 (14.960548400878906MB)
   free     = 3711384 (3.5394515991210938MB)
   80.86782919394004% used
To Space:
   capacity = 20447232 (19.5MB)
   used     = 0 (0.0MB)
   free     = 20447232 (19.5MB)
   0.0% used
PS Old Generation
   capacity = 256901120 (245.0MB)
   used     = 22278496 (21.246429443359375MB)
   free     = 234622624 (223.75357055664062MB)
   8.672012017697703% used

24741 interned Strings occupying 2987512 bytes.

首先会打印堆的一些相关配置,比如最大新生代、元空间的大小等;下面为堆的使用情况,包括新生代的 Eden 区、S0 区、S1 区以及老年代。

jmap 还可以将堆的信息以文件的形式保存下来,相当于文件快照,执行 jmap -dump:live,format=b,file=heap.bin 8825 命令:

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jmap -dump:live,format=b,file=heap.bin 8825
Dumping heap to /root/heap.bin ...
Heap dump file created

这个 heap.bin 可以使用 jhat 命令打开,是以 html 的形式展示的。

jhat

jhat 分析 Java 堆的命令,可以将堆中对象以 html 的形式显示出来,支持对象查询语言 OQL,命令内容如下:

jhat
jhat

现在执行 jhat -port 9999 heap.bin 来将刚刚保存的 heap.bin 以 html 展示出来:

代码语言:txt
AI代码解释
复制
[root@wupx ~]# jhat -port 9999 heap.bin
Reading from heap.bin...
Dump file created Tue May 12 22:31:55 CST 2020
Snapshot read, resolving...
Resolving 570997 objects...
Chasing references, expect 114 dots..................................................................................................................
Eliminating duplicate references..................................................................................................................
Snapshot resolved.
Started HTTP server on port 9999
Server is ready.

执行完毕后,打开 http://localhost:9999/ 就可以看到类的实例的堆占用情况,它是按照包名来分组的:

网页的底部还有许多 Query 方式:

下面以 OQL 为例,打开后是一个类似 SQL 查询的窗口,比如输入 select s from java.lang.String s where s.value.length >= 100 就可以查询字符串长度大于 100 的实例:

jstack

jstack堆栈跟踪工具,主要用于打印给定进程 pid 的堆栈信息,一般在发生死锁或者 CPU 100% 的时候排查问题使用,可以去查询当前运行的线程以及线程的堆栈信息是什么情况,命令内容如下:

jstack
jstack

下面执行 jstack -F 8825 > jstack.log 命令,将线程的信息保存下来:

代码语言:txt
AI代码解释
复制
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.161-b12 mixed mode):

"Attach Listener" #51805777 daemon prio=9 os_prio=0 tid=0x00007f971c001000 nid=0x9cd6 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"DestroyJavaVM" #55 prio=5 os_prio=0 tid=0x00007f9fc8009800 nid=0x227a waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"http-nio-8111-Acceptor-0" #52 daemon prio=5 os_prio=0 tid=0x00007f96c40c5800 nid=0x2653 runnable [0x00007f97c0df9000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
	at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
	at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
	- locked <0x00007f982c6213c8> (a java.lang.Object)
	at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:455)
	at java.lang.Thread.run(Thread.java:748)

"http-nio-8111-ClientPoller-0" #50 daemon prio=5 os_prio=0 tid=0x00007f9fc8e7e000 nid=0x2651 runnable [0x00007f97c21fb000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
	at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
	at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
	- locked <0x00007f982c622460> (a sun.nio.ch.Util$3)
	- locked <0x00007f982c622450> (a java.util.Collections$UnmodifiableSet)
	- locked <0x00007f982c622408> (a sun.nio.ch.EPollSelectorImpl)
	at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
	at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:787)
	at java.lang.Thread.run(Thread.java:748)

"Service Thread" #17 daemon prio=9 os_prio=0 tid=0x00007f9fc8379000 nid=0x229d runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread10" #15 daemon prio=9 os_prio=0 tid=0x00007f9fc8373800 nid=0x229b waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"VM Thread" os_prio=0 tid=0x00007f9fc831c000 nid=0x228d runnable 

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f9fc801e800 nid=0x227b runnable 

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f9fc8020800 nid=0x227c runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007f9fc837e000 nid=0x229e waiting on condition 

JNI global references: 357

因为内容比较多,截取了部分内容,可以看出会打印出线程的信息、状态以及堆栈,也会打印出 GC Task 的线程信息(ParallelGC 属于并行收集器,默认为 2 个线程),从中可以分析出每个线程都在做什么,如果服务器 CPU 占用高,可以看有多少个线程处于 RUNNABLE 状态,一般是由于处于 RUNNABLE 状态的线程过多,导致 CPU 过高;如果很多线程处于 TIMED_WAITING 状态,理论上 CPU 占用不会很高。

总结

本文主要对 JDK 常用的内置命令 javap、jps、jstat、jcmd、jmap、jhat、jstack 进行了简单讲解,大家可以自己在本机进行实践。

了解这些命令后会在死锁、CPU 占用过高问题的排查、程序性能调优上会有很大的帮助,以后还会介绍 JDK 自带的图形化工具以及 CPU 占用过高的排查实例。

最好的关系就是互相成就,大家的在看、转发、留言三连就是我创作的最大动力。

参考

https://docs.oracle.com/javase/8/docs/technotes/tools/index.html#basic

JDK 内置命令工具

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于STM32+LDC1000的循迹小车
每年的TI杯电子设计竞赛都会出A题~G题共七个题,我们团队平时主要做控制的多,所以这次竞赛我们选择控制类题目——自动循迹小车。该题题目及要求如下:
正念君
2019/06/26
2.6K0
基于STM32+LDC1000的循迹小车
2016年辽宁省电子设计大赛自动循迹小车制作心得[通俗易懂]
使用STM32F103的程序在这里:https://download.csdn.net/download/weixin_42089190/10456099
全栈程序员站长
2022/08/18
7710
2016年辽宁省电子设计大赛自动循迹小车制作心得[通俗易懂]
树莓派小车C语言循迹,自动循迹小车_单片机/STM32/树莓派/Arduino/开发板创意项目-聚丰项目-电子发烧友网…[通俗易懂]
金属探测LDC1314是根据电磁感应原理制成的,将一金属置于变化的磁场当中时,根据电磁感应原理就会在金属内部产生涡流,涡流产生的磁场反过来又影响原磁场,这种变化可以转换为电压幅值的变化,供相关电路进行检测。通过改变金属和线圈之间的距离得到不同的值,对前端探测到的数据进行再处理和分析,当其中一个线圈探测到铁丝则让小车向相反方向前进,若发现附近有硬币存在该探测器发出声音警报。
全栈程序员站长
2022/08/23
7730
c语言智能车跑道检测程序,基于金属检测的智能循迹小车设计
摘 要: 为解决当前循迹小车存在性能稳定性差的问题,提出一种基于金属检测的智能循迹小车设计方法。采用LDC1000设计一种金属循迹智能小车,介绍系统总体设计框架、硬件设计和软件设计。采用STM32单片机处理LDC1000电感数字转换器采集的路面信息,并通过串口通信将数据传给STC51单片机,由51单片机对数据进行处理,实现对报警、显示及电机驱动模块的控制,从而使小车能够沿着金属铁丝轨迹自动行驶,实现小车自动寻迹的目的。试验结果表明,整个系统的电路结构简单,性能稳定,实现了预期的智能小车循跡功能,具有很高的应用性。
全栈程序员站长
2022/09/06
1K0
c语言智能车跑道检测程序,基于金属检测的智能循迹小车设计
基于STC89C52的自动循迹小车项目
摘要:本文根据对目标金属物的非接触式探测定位和移动的具体要求,以STC89C52RC单片机为控制核心,结合驱动模块、三个电感模块(LDC1000电感数字传感器)、测速模块和显示模块,设计并实现了一种自动循迹小车。该小车能在规定的具有0.6-0.9mm细铁丝标识的平面跑道上自动循迹前进,且在行进过程中能够检测到硬币并报警,同时小车的运行时间、距离等信息可在显示屏上实时显示。经过多次测试表明,该循迹小车达到了预期的效果,自动循迹稳定,硬币识别准确,实时显示距离及时间效果好,抗干扰能力强。
全栈程序员站长
2022/09/06
1.4K0
基于STC89C52的自动循迹小车项目
基于LDC1000的自动循迹小车
大三上学期课程设计的题目选了做小车,需要使用的是TI公司的LDC1000或者LDC1314,题目如下:
全栈程序员站长
2022/06/26
7760
基于LDC1000的自动循迹小车
树莓派综合项目3:AI视觉机械臂小车(三)基本运动
树莓派综合项目3:AI视觉机械臂小车(一)蜂鸣器 树莓派综合项目3:AI视觉机械臂小车(二)轻触按键   本实验将实现履带车的基本运动,前进、后退、左转、右转。在以前的文章中有更基础细致的讲解可以参考: 树莓派基础实验34:L298N模块驱动直流电机实验 树莓派综合项目2:智能小车(一)四轮驱动
张国平
2021/05/17
1.7K1
树莓派综合项目3:AI视觉机械臂小车(三)基本运动
LDC1314 学习资料
LDC1314芯片是2016年TI杯全国电子设计竞赛指定使用芯片,为了调试方便制作了模块如下图,它配合4个线圈可以检测磁性材料,比如硬币和铁丝等,2016 比赛的题目就是小车检测铁丝。
全栈程序员站长
2022/06/26
5250
LDC1314 学习资料
【LDC1314】金属传感器(电感传感器)的调试技巧
这次调试的标准是按照2016年江苏省大学生电子设计竞赛的寻铁丝小车的题目要求为准的。
全栈程序员站长
2022/06/26
1.1K0
【LDC1314】金属传感器(电感传感器)的调试技巧
树莓派综合项目2:智能小车(一)四轮驱动
树莓派的小项目中,我首选了智能小车这个项目作为我探索的第一个目标,因为和很多小朋友一样,对遥控小汽车有种喜欢,特别是有过小时候欲求而不得的经历的大人们哈。
张国平
2020/09/27
3.6K0
树莓派综合项目2:智能小车(一)四轮驱动
工业机器人(三)——控制方案
控制方案 控制系统是机器人重要组成部分,其主要功能是接收来自传感器的检测信号,驱动机械臂中电动机工作,进而带动机械臂移动到预定位置。本推文通过简单的实例(微型舵机)对机器人控制的简要过程进行介绍,主要
联远智维
2022/01/20
9540
工业机器人(三)——控制方案
简易旋转倒立摆及控制系统实现方案_旋转倒立摆与pid控制
完整文档和源码:https://github.com/Kevincoooool/inverted-pendulum + 2017年成都信息工程大学 第六届“电协杯”电子设计竞赛
全栈程序员站长
2022/09/23
1.1K0
2016TI杯——寻迹小车
B题:自动循迹小车 1.任务 设计制作一个自动循迹小车。小车采用一片 TI公司LDC1314或LDC1000电感数字转换器作为循迹传感器,在规定的平面跑道自动按顺时针方向循迹前进。跑道的标识为一根直径0.6~0.9mm的细铁丝,按照图1的示意尺寸,用透明胶带将其贴在跑道上。图中所有圆弧的半径均为为20cm±2cm。
全栈程序员站长
2022/06/26
6500
2016TI杯——寻迹小车
树莓派基础实验34:L298N模块驱动直流电机实验
  直流电机是一种将直流电能转换为机械能的电动机,因其良好的调速性能而在电力拖动中得到广泛应用,用于驱动各种设备,如电风扇、遥控小车、电动车窗等,也非常适合作为机器人的行走机构。
张国平
2020/09/27
3.5K0
智能小车设计规划_智能循迹避障小车设计
该课题主要基于单片机的循迹、避障、WiFi、蓝牙等功能的智能小车,在一些特殊环境下有着特殊的意义。硬件控制以arduino为控制核心。采用超声波避障和红外避障传感器共同完成寻迹、避障功能,并将相关信号传送给单片机,经单片机控制系统分析判断后控制驱动芯片驱动直流电机实现小车前进、后退、左转、右转,停止。软件采用移植性较好的c语言编写,通过手机蓝牙App实现对智能小车的控制。通过TCP/UD协议以及WiFi无线操作系统完成远距离通过终端控制,并将所扫描的信息路线传输给服务器,终端图形界面通过Qt设计实现。通过多次测试使小车能无线遥控、避障、循迹功能。
全栈程序员站长
2022/11/02
2.2K0
智能小车设计规划_智能循迹避障小车设计
2016年四川省TI杯电子设计竞赛B题
B题:自动循迹小车 1.任务 设计制作一个自动循迹小车。小车采用一片 TI公司LDC1314或LDC1000电感数字转换器作为循迹传感器,在规定的平面跑道自动按顺时针方向循迹前进。跑道的标识为一根直径0.6~0.9mm的细铁丝,按照图1的示意尺寸,用透明胶带将其贴在跑道上。图中所有圆弧的半径均为为20cm±2cm。
全栈程序员站长
2022/06/26
7000
2016年四川省TI杯电子设计竞赛B题
2020朝花夕拾-不务正业的大学生做了什么比赛?[通俗易懂]
朝花夕拾,旧事重提之意。恰逢CSDN年终征文,所以写作本文为年终总结,实为大学四年的总结,和CSDN一起成长参与各类竞赛的回忆。
全栈程序员站长
2022/09/07
5380
2020朝花夕拾-不务正业的大学生做了什么比赛?[通俗易懂]
电子设计竞赛 | 拿过校内“一等奖”的作品
设计一款模拟人体生命体征模拟器,要求其能准确模拟人体生命的各种体征(呼吸,心跳,体温,声音);并且能够对相关参量进行有效控制。以呼吸或者心跳体征为主要模拟实现的功能:
李肖遥
2020/07/06
8310
伺服通俗解读 ——你真懂真理解伺服系统吗?
关于伺服、伺服驱动器、伺服电机、伺服系统,随便拿出去问,百分之九十九的人都是不熟悉不清楚不了解的,我想,就算是与伺服相关的工作人员,数控自动化等工控领域的技术人才,大多也觉得对伺服‘一知半解’。我接触
机器人网
2018/04/20
2.2K0
伺服通俗解读 ——你真懂真理解伺服系统吗?
基于STM32设计的避障寻迹小车
根据美国玩具协会在一项研究中,过去几年全球玩具销售增长与GDP的世界平均水平大致相同。但全球玩具市场的内部结构已经占据了巨大的位置变化:传统玩具的市场份额正在下降,高科技电子玩具正在蓬勃发展。全球玩具市场的高科技电子游戏2010年的年销售额增长了67%,但传统玩具的年销售额仅增长了1%。
DS小龙哥
2023/03/06
2K0
基于STM32设计的避障寻迹小车
推荐阅读
相关推荐
基于STM32+LDC1000的循迹小车
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档