JDK 工具命令使用详解架构师

一 概述

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)例如:

JDK 工具命令使用详解架构师
 

五 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"

 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/6823.html

(0)
上一篇 2021年7月17日
下一篇 2021年7月17日

相关推荐

发表回复

登录后才能评论