做了一些 1.8
与1.17.x
jdk对比,最重要的是实际操作一次。
这些是java自带的命令,属于离线,应急之用。
相关文章在此总结如下:
文章 | 地址 |
---|---|
jvm基本知识 | 地址 |
jvm类加载系统 | 地址 |
双亲委派模型与打破双亲委派 | 地址 |
运行时数据区 | 地址 |
运行时数据区-字符串常量池、程序计数器、直接内存 | 地址 |
jvm中对象创建流程与内存分配 | 地址 |
jvm对象内存布局 | 地址 |
GC基本原理 | 地址 |
命令行:
命令 | 英文 | 中文 |
---|---|---|
jps | jvm Process status tool | jvm进程状态工具,查看进程基本信息 |
jstat | jvm statistics monitoring tool | jvm统计监控工具、查看堆、GC详细信息 |
jinfo | java configuration info | 查看配置参数信息,支持部分参数运行时修改 |
jmap | java memory map | 分析堆内存工具、dump堆内存快照 |
jhat | java heap analysis tool | 堆内存dump文件解析工具 |
jstack | java stack trace | java 堆栈跟踪工具 |
可视化工具
工具 | 说明 | 缺点 |
---|---|---|
VisualVM | 性能分析可视化工具 | 不能在linux命令行这种交互方式(不介绍) |
查看 java
进程,相当于 linux 下的 ps 命令,它只列出java进程。
# 列出java程序进程ID和jar包全名称
jps
当无部署的java应用时,如下
注意: 此时 jps 只显示当前应用程序进程ID与一个jar,而不是 jar
包全名
[root@hadoop01 jk-demo]# nohup /data/soft/jdk-17.0.9/bin/java -Xms1024m -Xmx1024m -jar jk-demo.jar &
[1] 6634
[root@hadoop01 jk-demo]# nohup: 忽略输入并把输出追加到"nohup.out"
[root@hadoop01 jk-demo]# jps
6634 jar
6922 Jps
再来比较一下
[root@hadoop01 jk-demo]# nohup /data/soft/jdk-17.0.9/bin/java -Xms1024m -Xmx1024m -jar /data/soft/jk-demo/jk-demo.jar &
[1] 4778
[root@hadoop01 jk-demo]# nohup: 忽略输入并把输出追加到"nohup.out"
[root@hadoop01 jk-demo]# jps
5188 Jps
4778 jk-demo.jar
命令台输出
由此: 现在能清楚的知道进程ID对应的哪个jar包了
没有什么意义
[root@hadoop01 jk-demo]# jps -q
4778
11421
[root@hadoop01 jk-demo]# nohup /data/soft/jdk-17.0.9/bin/java -Xms1024m -Xmx1024m -jar /data/soft/jk-demo/jk-demo.jar 123 abc &
[1] 16859
[root@hadoop01 jk-demo]# nohup: 忽略输入并把输出追加到"nohup.out"
[root@hadoop01 jk-demo]# jps -m
16859 jk-demo.jar 123 abc
17053 Jps -m
[root@hadoop01 soft]# jps -v
19137 Jps -Dapplication.home=/data/soft/jdk1.8 -Xms8m
16859 jk-demo.jar -Xms1024m -Xmx1024m
输出jar包所在的绝对路径
[root@hadoop01 soft]# jps -l
21845 sun.tools.jps.Jps
16859 /data/soft/jk-demo/jk-demo.jar
jstat可以查看java程序运行时相关信息,可以通过它查看运行时堆信息的相关情况。
jstat -<options> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
options由以下值构成
参数 | 详解 |
---|---|
-class | 显示ClassLoader的相关信息 |
-compiler | compiler 显示 JIT编译的相关信息 |
-gc | 显示与GC相关信息 |
-gccapacity | gccapacity 显示各个代的容量和使用情况 |
-gccause | 显示垃圾收集相关信息(同-gcutil),同时显示最后一次或当前正在发生的垃圾收集的诱发原因 |
-gcnew | gcnew 显示新生代信息 |
-gcnewcapacity | gcnewcapacity 显示新生代大小和使用情况 |
-gcold | gcold 显示老年代信息 |
-gcoldcapacity | gcoldcapacity 显示老年代大小 |
-gcpermcapacity | gcpermcapacity 显示永久代大小 |
-gcutil | gcutil 显示垃圾收集信息 |
下面输出的是进程内存区域及GC详细信息
jstat -gc 16859 250 4
16859 : 进程ID
250 : 采样间隔 250ms,不带单位默认 ms,可以写成 1s
4 : 采样数4
由上图可知,信息直观比较细
参数详解如下
参数 | 详解 |
---|---|
S0C | C 容量的意思,年轻代中第一个survivor区(幸存区)的容量(单位kb) |
S1C | 年轻代中第二个survivor区(幸存区)的容量(单位kb) |
S0U | U 已使用的意思,年轻代中第一个survivor(幸存区)目前已使用空间(单位kb) |
S1U | 年轻代中第二个survivor(幸存区)目前已使用空间(单位kb) |
EC | 年轻代中Eden的容量(单位kb) |
EU | 年轻代中Eden目前已使用空间(单位kb) |
OC | old代的容量是(单位kb) |
OU | old代目前已使用空间(单位kb) |
MC | metaspace的容量(单位kb) |
MU | metaspace目前已使用空间(单位kb) |
CCSC | 压缩类空间大小 |
CCSU | 压缩类空间使用大小 |
YGC | 从应用程序启动到采样时年轻代中gc次数 |
YGCT | 从应用程序启动到采样时年轻代中gc所用时间(s) |
FGC | 从应用程序启动到采样时old代(全gc)gc次数,FGC不同的垃圾回收器的意义还有点不一样,要注意 |
FGCT | 从应用程序启动到采样时old代(全gc)gc所用时间(s) ,FGC不同的垃圾回收器的意义还有点不一样,要注意 |
GCT | 从应用程序启动到采样时gc用的总时间(s) |
下面输出的是进程内存区域百分百及GC详细信息。统计后的信息。
jstat -gcutil 16859 1s 5
16859 : 进程ID
250 : 采样间隔 250ms,不带单位默认 ms,可以写成 1s
5 : 采样数5
参数 | 详解 |
---|---|
S0 | survivor第一个区使用率 |
S1 | survivor第二个区使用率 |
E | Eden使用率 |
O | 老年代使用率 |
M | 元空间使用率 |
CCS | 压缩空间使用率 |
# jdk 1.17.x
/data/soft/jdk-17.0.9/bin/jstat -gcutil 16859 1s 5
jinfo可以用来查看正在运行的java程序的扩展参数,甚至支持修改运行时过程中的部分参数
jinfo [option] <pid>
参数详解
参数 | 详解 |
---|---|
-flags | 打印虚拟机 vm 参数 |
-flag name | 打印指定虚拟机 vm 参数 |
-flag [+/-] name | 打开或关闭虚拟机参数 |
-flag name=value | 设置指定虚拟机参数的值 |
# jdk 1.8
jinfo -flags 16859
/data/soft/jdk-17.0.9/bin/jinfo -flags 16859
主要输出 jvm
的配置参数
jmap用来查看堆内存使用状况,一般结合jhat使用。
jmap 16859
这个命令常用。
# jdk 1.8
jmap -heap 16859
[root@hadoop01 ~]# jmap -heap 16859
Attaching to process ID 16859, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 17.0.9+11-LTS-201
using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 1073741824 (1024.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 643825664 (614.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 22020096 (21.0MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 1048576 (1.0MB)
Heap Usage:
G1 Heap:
regions = 1024
capacity = 1073741824 (1024.0MB)
used = 78066944 (74.450439453125MB)
free = 995674880 (949.549560546875MB)
7.270550727844238% used
G1 Young Generation:
Eden Space:
regions = 66
capacity = 438304768 (418.0MB)
used = 69206016 (66.0MB)
free = 369098752 (352.0MB)
15.789473684210526% used
Survivor Space:
regions = 7
capacity = 8388608 (8.0MB)
used = 7832832 (7.469970703125MB)
free = 555776 (0.530029296875MB)
93.3746337890625% used
G1 Old Generation:
regions = 2
capacity = 627048448 (598.0MB)
used = 1028096 (0.98046875MB)
free = 626020352 (597.01953125MB)
0.16395798494983277% used
*
前缀。如果指定了 live
子选项,则只计算活动的对象。jmap -histo 16859
这个命令用得不多。
/data/soft/jdk-17.0.9/bin/jmap -clstats 16859
[root@hadoop01 jdk-17.0.9]# /data/soft/jdk-17.0.9/bin/jmap -clstats 16859
ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bcd1c0e0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bd13bce0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc84dcd0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc6009a0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc8dddd0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x0000000000000000 0x00007fd1bc470180 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc871ff0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bca168f0 1 512 394 jdk.internal.reflect.DelegatingClassLoader
0x00007fd147084530 0x00007fd147086808 0x00007fd1bc37c720 54 47104 44253 jdk.internal.loader.ClassLoaders$AppClassLoader
0x00007fd148001000 0x00007fd147084530 0x00007fd1bc416790 4131 2570880 2567758 org.springframework.boot.loader.LaunchedURLClassLoader
1 256 127 + hidden classes
0x00007fd1470094d8 0x0000000000000000 0x00007fd1bc84c250 1 512 394 jdk.internal.reflect.DelegatingClassLoader
0x0000000000000000 0x0000000000000000 0x00007fd1bc345440 2379 868352 864303 <boot class loader>
239 94464 61213 + hidden classes
0x00007fd1470094d8 0x0000000000000000 0x00007fd1bc890290 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd147086808 0x0000000000000000 0x00007fd1bc34e4b0 28 19456 18176 jdk.internal.loader.ClassLoaders$PlatformClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bcd0f5a0 1 512 394 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x0000000000000000 0x00007fd1bc872160 1 384 237 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc84d0e0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bcaec090 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc9b9dd0 1 512 390 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc9e47f0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x0000000000000000 0x00007fd1bc84c680 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc788850 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bca849c0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc84d1a0 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x0000000000000000 0x00007fd1bc8b5a30 1 384 237 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc468670 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x00007fd148001000 0x00007fd1bc872420 1 512 429 jdk.internal.reflect.DelegatingClassLoader
0x00007fd1470094d8 0x0000000000000000 0x00007fd1bca3d970 1 512 429 jdk.internal.reflect.DelegatingClassLoader
Total = 28 6856 3612544 3565598
ChunkSz: Total size of all allocated metaspace chunks
BlockSz: Total size of all allocated metaspace blocks (each chunk has several blocks)
jmap dump:
快照
文件;以二进制格式转储 java 堆到指定文件中。如果指定了 live 子选项,堆中只有活动的对象会被转储。浏览 heap dump 可以使用 jhat 读取生成的文件,也可以使用MAT等堆内存分析工具。**注意:**这个命令执行,jvm会将整个heap的信息dump写入到一个文件,heap 如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证 dump 的信息是可靠的,所以会暂停应用,线上系统慎用!
/data/soft/jdk-17.0.9/bin/jmap -dump:format=b,file=heapdump.hprof 16859
java 生成堆转储的方式有多种:
-XX:+HeapDumpOnOutOfMemoryError
选项,则抛出 OutOfMemoryError 时,会自动挂靠堆转储。jhat [ options ] heap -dump -file
/data/soft/jdk-17.0.9/bin/jhat ./heapdump.hprof
**注意:**jdk1.8是有这个命令的。
jhat从jdk1.9的时候已经删除了(JEP 241: Remove the jhat Tool)。现在Oracle官方推荐的分析工具是Eclipse Memory Analyzer Tool (MAT) 和 VisualVM。
jstack是java虚拟机自带的一种堆栈跟踪工具,用于生成java虚拟机当前时刻的线程快照。
线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程 出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等等。
线程快照里留意下面几种状态
使用方式
命令 | 详解 |
---|---|
jstack [ option ] pid | 查看当前时间点,指定里程的dump堆栈信息 |
jstack [ option ] pid > 文件 | 将当前时间点的指定进程的dump堆栈信息,写入到指定文件中(若存在则覆盖,不存在,自动生成) |
jstack [ option ] executable core | 查看当前时间点,core文件的dump堆栈信息 |
jstack [ option ] [ server_id@ ] remote server ip or hostname | 查看当前时间点,远程机器的dump堆栈信息 |
可选参数说明
-F :当里程挂起,此时 `jstack [-l] pid` 是没有响应的,这时候可使用此参数强制打印堆栈信息,强制jstack,一般情况不需要使用。
-m :打印java和native c/c++ 框架的所有栈信息。可以打印jvm的堆栈,以及Native的栈帧,一般应用排查不需要使用
-l :长列表。打印关于锁的附加信息。例如属于 java.util.concurrent 的 ownable synchronizers 列表,会使用jvm停顿长久得多,比如普通的jstack可能几毫秒,和一次GC没区别,加了-l就是近一秒的时间,-l 建议不要使用,一般情况下不需要使用。
-h or -hel : 打印帮助信息
/data/soft/jdk-17.0.9/bin/jstack 16859
/data/soft/jdk-17.0.9/bin/jstack 16859 > jvm_stack_info_16859
/data/soft/jdk-17.0.9/bin/jstack -l 16859 | grep 'java.lang.Thread.State' | wc -l
至此,java自带的命令介绍就结束了。如有疑问,欢迎留言。