一 概述
Java应用,线上查看gc,堆分配,堆使用是很常见的需求。JDK自带的命令可以查看很多信息,掌握后对我们定位问题能起到很大的帮助。
本文总结相关命令的使用。
二 jstack:查看java线程信息
(1)用法:
常用方式:jstack [-l] <pid>
jstack -l 912 2018-05-27 10:34:53 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode): 。。。。。。 "main" #1 prio=5 os_prio=31 tid=0x00007fa084000000 nid=0x2803 waiting on condition [0x000070000b354000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386) at HelloWorld.main(HelloWorld.java:12) Locked ownable synchronizers: - None "VM Thread" os_prio=31 tid=0x00007fa083819000 nid=0x3103 runnable "GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fa08301b800 nid=0x1c07 runnable 。。。。。。 JNI global references: 6
说明:
"main" 线程名称。用户自己的程序最好是线程名称
prio=5 线程优先级默认是5
tid= 0x00007fa084000000 唯一标识
nid=0x2803 对应系统线程的id和top出来看到的pid是对应的(十进制转16进制)
TIMED_WAITING线程状态
状态如下:
1,死锁 Deadlock(重要)
2,等待资源 Waiting on condition (重要)
3,等待获取监视器waiting on monitor entry
4,阻塞Blocked
5,执行中Runnable
6,暂停Suspended
7,对象等待中Object.wait()或TIMED_WAITING
8,停止Parke
(2)场景:查看cpu使用率最高的线程
1) 查看cpu使用率最高的线程top10:
命令:ps -mp [pid] -o THREAD,tid,time | sort -k2 -nr | head -10
其中:[pid] 是进程号
[root]# ps -mp 1000 -o THREAD,tid,time | sort -k2 -nr | head -10 root 10.6 - - - - - - 1-18:45:53 root 5.6 19 - futex_ - - 10784 22:35:57 root 0.4 19 - futex_ - - 10770 01:51:14 root 0.2 19 - futex_ - - 10712 00:52:56 root 0.2 19 - futex_ - - 10711 00:52:55 root 0.2 19 - futex_ - - 10710 00:52:56 root 0.2 19 - futex_ - - 10709 00:52:55 root 0.2 19 - futex_ - - 10708 00:52:55 root 0.2 19 - futex_ - - 10707 00:52:55 root 0.2 19 - futex_ - - 10706 00:52:53
2) 查看Java 线程信息:
命令:tid=`printf "%x\n" [tid]`; echo "tid : ${tid}" ; jstack -l [pid] | grep ${tid} -A 10
其中:[pid] :进程id
[tid] :线程id
[root]# tid=`printf "%x\n" 10784`; echo "tid : ${tid}" ; ./jstack -l 1000 | grep ${tid} -A 10 tid : 2a20 "ContainerBackgroundProcessor[StandardEngine[Catalina]]" #48 daemon prio=5 os_prio=0 tid=0x00007f344c504000 nid=0x2a20 waiting on condition [0x00007f33b23b3000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1340) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - None
三 jstat:查看堆内存使用及gc信息
(1)用法:
常用方式: jstat -gc vmid
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 3392.0 3392.0 0.0 2185.4 27328.0 21297.2 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076 3392.0 3392.0 0.0 2185.4 27328.0 21678.1 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076 3392.0 3392.0 0.0 2185.4 27328.0 22709.9 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076 3392.0 3392.0 0.0 2185.4 27328.0 23611.4 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076 3392.0 3392.0 0.0 2185.4 27328.0 24553.2 68288.0 3429.1 9216.0 8854.1 1024.0 939.1 3 0.039 2 0.037 0.076
说明:
S0C :S0 总大小
S1C :S1 总大小
S0U :S0 使用大小
S1U :S1 使用大小
EC :伊甸区总大小
EU :伊甸区使用大小
OC :老年代总大小
OU :老年代使用大小
MC :Metaspace 总大小
MU :Metaspace 使用大小
CCSC :CompressedClassSpace总大小
CCSU :CompressedClassSpace使用大小
YGC :Young GC 次数
YGCT :Young GC 消耗总时间
FGC :FullGC 次数
FGCT :FullGC 消耗总时间
GCT :GC总消耗时间
三 jmap
(1)查看堆设置:jmap -heap [pid]
Attaching to process ID 18095, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.31-b07 using thread-local object allocation. Mark Sweep Compact GC Heap Configuration: MinHeapFreeRatio = 40 最小堆使用比例 MaxHeapFreeRatio = 70 最大堆可用比例 MaxHeapSize = 104857600 (100.0MB) 最大堆空间大小 NewSize = 34930688 (33.3125MB) 新生代分配大小 MaxNewSize = 34930688 (33.3125MB) 最大可新生代分配大小 OldSize = 69926912 (66.6875MB) 老生代大小 NewRatio = 2 (old/young generations) 新生代比例 SurvivorRatio = 8 (young/suvivor )新生代与suvivor的比例 MetaspaceSize = 21807104 (20.796875MB) Metaspace大小—— Metaspace是1.8后出现的,替代perm区 CompressedClassSpaceSize = 1073741824 (1024.0MB) CompressedClassSpace大小 MaxMetaspaceSize = 52428800 (50.0MB) : 最大 Metaspace大小 G1HeapRegionSize = 0 (0.0MB)
(2)查看堆占用:jmap -histo [pid] | sort -k2 -nr | head -30
num #instances #bytes class name ---------------------------------------------- 2: 2505 354616 [C 5: 1698 40752 java.lang.String 3: 677 141992 [B 6: 580 30632 [Ljava.lang.Object; 4: 493 56208 java.lang.Class 1: 443 4639632 [I 11: 258 4128 java.lang.Integer 10: 230 5520 java.lang.StringBuilder 8: 217 6944 java.io.File 13: 118 3776 java.util.Hashtable$Entry 7: 115 8280 java.lang.reflect.Field 12: 98 3920 java.lang.ref.SoftReference 9: 95 6080 java.net.URL 17: 91 2184 java.net.Parts 15: 83 2952 [Ljava.lang.String; 18: 67 2144 java.util.HashMap$Node 16: 65 2600 java.lang.ref.Finalizer 25: 53 1696 java.util.concurrent.ConcurrentHashMap$Node
(3)dump 堆数据: jmap -dump:format=b,file=heap.hprof [pid]
jmap -dump:format=b,file=heap.hprof 1000 Dumping heap to /tmp/heap.hprof ... Heap dump file created
四 jhat:html方式查看dump文件分析结果
(1)用法:
Usage: jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>
常用方式:jhat -port 5000 ./heap.hprof
其中 500 是端口,一般用于本地分析对使用情况,html方式分析dump文
(2)例如:
五 javap:用于分析class文件
(1)用法:
用法: javap <options> <classes> 其中, 可能的选项包括: -help --help -? 输出此用法消息 -version 版本信息 -v -verbose 输出附加信息 -l 输出行号和本地变量表 -public 仅显示公共类和成员 -protected 显示受保护的/公共类和成员 -package 显示程序包/受保护的/公共类 和成员 (默认) -p -private 显示所有类和成员 -c 对代码进行反汇编 -s 输出内部类型签名 -sysinfo 显示正在处理的类的 系统信息 (路径, 大小, 日期, MD5 散列) -constants 显示最终常量 -classpath <path> 指定查找用户类文件的位置 -cp <path> 指定查找用户类文件的位置 -bootclasspath <path> 覆盖引导类文件的位置
(2)举例:
java类:
public class HelloWorld { public static void main(String[] args) { System.out.println("hello world!"); } }
查看反编译信息:javap -c HelloWorld ; 可用于执行信息
javap -c HelloWorld 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 }
查看附加信息:javap -v HelloWorld;可以看看字节码的处理顺序等
javap -v HelloWorld Classfile /Users/shilei/Root/Develop/DevelopSpace/Demo/lucene/target/classes/HelloWorld.class Last modified May 25, 2018; size 534 bytes MD5 checksum e75a26fd4cfa5da79c54f66e06b5cf83 Compiled from "HelloWorld.java" public class HelloWorld minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #6.#20 // java/lang/Object."<init>":()V #2 = Fieldref #21.#22 // java/lang/System.out:Ljava/io/PrintStream; #3 = String #23 // hello world! #4 = Methodref #24.#25 // java/io/PrintStream.println:(Ljava/lang/String;)V #5 = Class #26 // HelloWorld #6 = Class #27 // java/lang/Object #7 = Utf8 <init> #8 = Utf8 ()V #9 = Utf8 Code #10 = Utf8 LineNumberTable #11 = Utf8 LocalVariableTable #12 = Utf8 this #13 = Utf8 LHelloWorld; #14 = Utf8 main #15 = Utf8 ([Ljava/lang/String;)V #16 = Utf8 args #17 = Utf8 [Ljava/lang/String; #18 = Utf8 SourceFile #19 = Utf8 HelloWorld.java #20 = NameAndType #7:#8 // "<init>":()V #21 = Class #28 // java/lang/System #22 = NameAndType #29:#30 // out:Ljava/io/PrintStream; #23 = Utf8 hello world! #24 = Class #31 // java/io/PrintStream #25 = NameAndType #32:#33 // println:(Ljava/lang/String;)V #26 = Utf8 HelloWorld #27 = Utf8 java/lang/Object #28 = Utf8 java/lang/System #29 = Utf8 out #30 = Utf8 Ljava/io/PrintStream; #31 = Utf8 java/io/PrintStream #32 = Utf8 println #33 = Utf8 (Ljava/lang/String;)V { public HelloWorld(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 7: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHelloWorld; public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 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 LineNumberTable: line 9: 0 line 10: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 args [Ljava/lang/String; } SourceFile: "HelloWorld.java"