Jvm常用的命令行工具(二)

接上篇,本文继续学习其它的JDK工具

4.jmap :Java内存映像工具(Memory Map for Java)

jmap 命令用于生成堆转储快照(heapdump 或者dump文件),如果不适用jmap工具,通常要想获取Java堆转储快照, 需要使用一些比较“暴力”得手段,比如在vm args中使用:-XX:+HeapDumpOnOutOfMemoryError参数,可以在虚拟机OOM异常出现之后自动生成dump文件,通过-XX:+HeapDumpOnCtrlBreak参数则可以使用[Ctrl]+[Break]键让虚拟机生成dump文件,或者在Linux中通过kill -3命令发送进程退出信号“吓唬”一下虚拟机,也能拿到dump文件。

jmap得作用不仅仅是为了获取dump文件,它还可以查询finalize执行队列、Java堆和永久代得详细信息,如空间使用率、当前使用得哪种收集器等。

jmap在Windows平台下也有很多功能是受限得,除了生成dump文件得-dump选项和用于查看每个类得实例、空间占用统计得-histo选项,其他参数都只能在linux/solaris下使用

jmap命令格式

jmap [option] vmid
选项 作用
-dump 生成Java堆转储快照,格式为:-dump:[live,]format=b,file=,其中live子参数说明是否只dump出存活的对象
-finalizeinfo 显示在F-Queue中等待Finalizer线程执行finalize方法的对象
-heap 显示Java堆详细信息,如使用哪种回收器、参数配置、分代状况等
-histo 显示堆中对象统计信息,包括类、实例数量、合计容量
-permstat 以ClassLoader 为统计口径显示永久代内存状态 jdk1.7
-F 当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照

例子:

[root@VM_0_13_centos ~]# jmap -dump:format=b,file=eladmin.bin 32534
Dumping heap to /root/eladmin.bin ...
Heap dump file created


[root@VM_0_13_centos ~]# jmap -finalizerinfo 32534
Attaching to process ID 32534, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.201-b09
Number of objects pending for finalization: 0


[root@VM_0_13_centos ~]# jmap -heap 32534
Attaching to process ID 32534, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.201-b09

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 268435456 (256.0MB)

[root@VM_0_13_centos ~]# jmap -histo 32534
省略。。。。。。
6725:             1              8  sun.util.locale.provider.CalendarDataUtility$CalendarWeekParameterGetter
6726:             1              8  sun.util.locale.provider.TimeZoneNameUtility$TimeZoneNameGetter
6727:             1              8  sun.util.resources.LocaleData$LocaleDataResourceBundleControl

Dump 生产堆内存信息
/usr/lib # jmap -dump:format=b,file=eip.dump.hprof 10
Dumping heap to /usr/lib/eip.dump.hprof ...
Heap dump file created

从K8S中到处堆内存日志文件
[root@icp-client ~]# kubectl cp -n boss-dev eip-service-6f9564b945-bsj2f:/usr/lib/eip.dump.hprof ~
tar: removing leading '/' from member names

5. jhat:虚拟机堆转储快照分析工具(JVM Heap Analysis Tool)

一般jhat命令与jmap命令搭配使用,通过jhat分析jmap生成的堆转储快照,jhat 内置了一个微型的HTTP/HTML服务器,生成dump文件的分析结果后,可以通过浏览器来查看。

但一般在实际使用中,除非没有其他工具可以,一般没人用这个,原因有二:

  • 一是一般不会在部署应用程序的服务器上直接分析dump文件,即使可以这样做,也会尽量将dump文件复制到其他机器上分析,比如拷贝到我们本地进行分析,因为分析工作时一个耗时而且消耗硬件资源的过程,既然都要在其他机器上进行了,就米有必要收到命令行工具的限制了;
  • 另一个原因时jhat的分析功能相对来说比较简陋,后文会介绍到VisualVM以及专业分析dump文件的工具,都会更加强大而专业。

例子:

[root@VM_0_13_centos ~]# jhat eladmin.bin 
Reading from eladmin.bin...
Dump file created Tue Dec 31 12:50:29 CST 2019
Snapshot read, resolving...
Resolving 1556642 objects...
Chasing references, expect 311 dots.......................................................................................................................................................................................................................................................................................................................
Eliminating duplicate references.......................................................................................................................................................................................................................................................................................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

屏幕显示“Service is ready”后,在浏览器输入http://host:7000/就可以看到分析结果。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JVFQ35aP-1586919309608)(62E6E0B49418409AB3E7466BDFE7B6A7)]

分析结果默认是以包为单位进行分组显示,分析内存泄漏问题主要会使用到其中的“Heap Histogram”与OQL页签的功能,前者可以找到内存中总容量最大的对象,后者是标准的对象查询语言,使用类似的SQL语法对内存中的对象进行查询统计。

6. jstack : Java堆栈跟踪工具(Stack Trace for Java)

jstack 命令用于生成虚拟机当前时刻的线程快照(thread dump 或者java core文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做了什么事情,或者等待了什么资源。

jstack 命令格式

jstack [option] vmid
选项 作用
-F 当正常输出的请求不被响应时,强制输出线程堆栈
-l 除堆栈外,显示关于锁的附加信息
-m 如果调用到本地方法,可以显示C/C++的堆栈

例子:

[root@VM_0_13_centos ~]# jstack -l 32534
2019-12-31 13:43:09
Full thread dump Java HotSpot(TM) Client VM (25.201-b09 mixed mode):

"Attach Listener" #167 daemon prio=9 os_prio=0 tid=0xdf4bb800 nid=0xed0 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
	- None

"logback-9" #62 daemon prio=5 os_prio=0 tid=0xdf4d1800 nid=0x679 waiting on condition [0xde0ba000]
   java.lang.Thread.State: TIMED_WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0xe9e94c18> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
	at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
	at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
	- None
[root@VM_0_13_centos ~]# jstack -F 32534
省略

jdk 1.5中,java.lang.Thread类新增了一个getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象。

Jprofiler:https://blog.csdn.net/wytocsdn/article/details/79258247

关于JVM与JC分析的工具先到这,后续根据我们的项目看能不能再搞一篇JVM 分析的实战篇。

附:

疫情也不知道5月份能不能过去,最近面试大厂也只能视频或者在线面试,难度大大提高,因为要当场调试出编程题的结果,像我这种菜鸡,面一次挂一次,我太难了,公司又快要从西二旗搬到亦庄去,留给同志们的时间不多了

你可能感兴趣的:(JVM)