编程的魅力
首页
分类
标签
归档
动态
关于我
hyuga
2020-07-27
105
2020-07-27 20:26:17
转载
JDK故障命令行工具
# 转载 - 原作者:水狐 # JDK 命令行工具 - jps (JVM Process Status): 查看java进程和id - jstat( JVM Statistics Monitoring Tool): 远程获取GC文本信息 - jinfo (Configuration Info for Java) :获取并修改虚拟机启动的配置信息 - jmap (Memory Map for Java) :生成堆转储快照dump文件 - jhat (JVM Heap Dump Browser ) : 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果 - jstack (Stack Trace for Java):生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。 # JDK可视化工具 - VisualVM(第三方,线上最为强大的可视化工具) - 阿里arthas(强大,而且自带反编译) - JConsole(自带的,除了没有dump快照功能,基本有了) - JProfiler # JDK 命令行工具 - jps (JVM Process Status): 查看java进程和id 类似 UNIX 的 ps 命令。显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一 ID ``` jps -q :只输出进程的本地虚拟机唯一 ID。 jps -v:输出虚拟机进程启动时 JVM 参数。 jps -m:输出传递给 Java 进程 main() 函数的参数。 jps -l:输出主类的全名,如果进程执行的是 Jar 包,输出 Jar 路径。 jps -l 7360 firstNettyDemo.NettyClient2 17396 7972 org.jetbrains.jps.cmdline.Launcher 16492 sun.tools.jps.Jps 17340 firstNettyDemo.NettyServer ``` - jstat( JVM Statistics Monitoring Tool): 远程获取GC文本信息 用于远程收集 HotSpot 虚拟机各方面的运行数据; `jstat -
[-t] [-h
]
[
[
]]` 常见用法: ``` jstat -gc -h3 31736 1000 10 //表示分析进程 id 为 31736 的 gc 情况,每隔 1000ms 打印一次记录,打印 10 次停止,每 3 行后打印指标头部 jstat -class vmid :显示 ClassLoader 的相关信息; jstat -compiler vmid :显示 JIT 编译的相关信息; jstat -gc vmid :显示与 GC 相关的堆信息; jstat -gccapacity vmid :显示各个代的容量及使用情况; jstat -gcnew vmid :显示新生代信息; jstat -gcnewcapcacity vmid :显示新生代大小与使用情况; jstat -gcold vmid :显示老年代和永久代的信息; jstat -gcoldcapacity vmid :显示老年代的大小; jstat -gcpermcapacity vmid :显示永久代大小; jstat -gcutil vmid :显示垃圾收集信息; ``` - jinfo (Configuration Info for Java) :获取并修改虚拟机启动的配置信息 查看JVM配置信息 - jinfo vmid :输出当前 jvm 进程的全部参数和系统属性 (第一部分是系统的属性,第二部分是 JVM 的参数)。 - jinfo -flag name vmid :输出对应名称的参数的具体值。比如输出 MaxHeapSize、查看当前 jvm 进程是否开启打印 GC 日志 ( -XX:PrintGCDetails :详细 GC 日志模式,这两个都是默认关闭的)。 例如: ``` jinfo -flag MaxHeapSize 17340 -XX:MaxHeapSize=2124414976 jinfo -flag PrintGC 17340 -XX:-PrintGC 修改JVM配置信息 使用 jinfo 可以在不重启虚拟机的情况下,可以动态的修改 jvm 的参数。尤其在线上的环境特别有用,请看下面的例子: jinfo -flag [+|-]name vmid 开启或者关闭对应名称的参数。 jinfo -flag PrintGC 17340 -XX:-PrintGC jinfo -flag +PrintGC 17340 jinfo -flag PrintGC 17340 -XX:+PrintGC ``` - jmap (Memory Map for Java) :生成堆转储快照dump文件 将执行中的堆内容进行快照导出dump文件,做以后的分析使用,可以通过 jhat、Visual VM 等工具分析该堆文件。获取GC年龄,指定空间等等 ``` jmap -dump:format=b,file=C:\Users\SnailClimb\Desktop\heap.hprof 17340 Dumping heap to C:\Users\SnailClimb\Desktop\heap.hprof ... Heap dump file created ``` - jhat (JVM Heap Dump Browser ) : 用于分析 heapdump 文件,它会建立一个 HTTP/HTML 服务器,让用户可以在浏览器上查看分析结果 分析如上dump文件 jstack (Stack Trace for Java):生成虚拟机当前时刻的线程快照,线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合。 生成线程快照的目的主要是定位线程长时间出现停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者在等待些什么资源。 # 查看死锁实例 ``` public class DeadLockDemo { private static Object resource1 = new Object();//资源 1 private static Object resource2 = new Object();//资源 2 public static void main(String[] args) { new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); } } }, "线程 1").start(); new Thread(() -> { synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource1"); synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); } } }, "线程 2").start(); } } ``` 线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到执行然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。 //首先查到进程 ``` 13792 KotlinCompileDaemon 7360 NettyClient2 17396 7972 Launcher 8932 Launcher 9256 DeadLockDemo jstack 9256 Found one Java-level deadlock: ============================= "线程 2": waiting to lock monitor 0x000000000333e668 (object 0x00000000d5efe1c0, a java.lang.Object), which is held by "线程 1" "线程 1": waiting to lock monitor 0x000000000333be88 (object 0x00000000d5efe1d0, a java.lang.Object), which is held by "线程 2" Java stack information for the threads listed above: =================================================== "线程 2": at DeadLockDemo.lambda$main$1(DeadLockDemo.java:31) - waiting to lock <0x00000000d5efe1c0> (a java.lang.Object) - locked <0x00000000d5efe1d0> (a java.lang.Object) at DeadLockDemo$$Lambda$2/1078694789.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) "线程 1": at DeadLockDemo.lambda$main$0(DeadLockDemo.java:16) - waiting to lock <0x00000000d5efe1d0> (a java.lang.Object) - locked <0x00000000d5efe1c0> (a java.lang.Object) at DeadLockDemo$$Lambda$1/1324119927.run(Unknown Source) at java.lang.Thread.run(Thread.java:748) Found 1 deadlock. ``` # JDK可视化工具 VisualVM(第三方,线上最为强大的可视化工具) 1. 显示虚拟机进程以及进程的配置、环境信息(jps、jinfo)。 2. 监视应用程序的 CPU、GC、堆、方法区以及线程的信息(jstat、jstack)。 3. dump 以及分析堆转储快照(jmap、jhat)。 4. 方法级的程序运行性能分析,找到被调用最多、运行时间最长的方法。 5. 离线程序快照:收集程序的运行时配置、线程 dump、内存 dump 等信息建立一个快照,可以将快照发送开发者处进行 Bug 反馈。 6. 其他 plugins 的无限的可能性...... 阿里arthas(强大,而且自带反编译) JConsole(自带的,除了没有dump快照功能,基本有了) JConsole 是基于 JMX 的可视化监视、管理工具。可以很方便的监视本地及远程服务器的 java 进程的内存使用情况。你可以在控制台输出console命令启动或者在 JDK 目录下的 bin 目录找到jconsole.exe然后双击启动。 如果需要远程访问,那么服务器主机需要加上启动参数 ``` -Djava.rmi.server.hostname=外网访问 ip 地址 -Dcom.sun.management.jmxremote.port=60001 //监控的端口号 -Dcom.sun.management.jmxremote.authenticate=false //关闭认证 -Dcom.sun.management.jmxremote.ssl=false ``` - javac TestSyn.java 编译class - javap -v TestSyn.class 编译内存指令
JAVA
Dump
评论
发布
留言
评论