JVM调试工具

在软件开发过程中,很重要的一点是内存的占用,良好的内存控制可以提升服务器运行的流畅性,最根本的是开发过程中注意编码实现方式,运用JVM相关知识尽可能优化我们的程序。甚至有时线上运行的项目运行状况不良好,如出现内存溢出和内存泄漏,那么此时我们将使用一些工具来发现和定位问题,然后进行优化。JVM自带了一些基础的故障处理工具,包括jps、jinfo、jstat、jmap、jhat和jstack。

内存泄露 :是指程序在申请内存后,无法释放已申请的内存空间就造成了内存泄漏,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。在使用调试工具检测时,往往表现为老年代占用比例接近或等于100%,而Full GC的次数不断增加,或进程98%的时间用于GC,每次回收的比例 却不超过2%。

jps

执行jps命令可以获取到当前虚拟机中正在运行的java程序,以及对应的进程号,输出格式如下,前面数字代表的便是进程号

#jps
21444 Launcher
5144 Jps
17084 ConfigServerApplication

ps aux | egrep “MEM|pid”

查看操作系统内存占用

jmap

jmap使用主要是打印某一时刻,某个进程的jvm堆信息

Usage:
    jmap [option] <pid>
        (to connect to running process)
        option:选项参数,不可同时使用多个选项参数。
		pid:Java进程id。
    jmap [option] <executable <core>
        (to connect to a core file)
        executable:产生核心dump的Java可执行文件。
		core:需要打印配置信息的核心文件
    jmap [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)
        remote-hostname-or-ip:远程调试的主机名或ip。
		server-id:可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标示服务器

where <option> is one of:
    <none>               to print same info as Solaris pmap
    -heap                to print java heap summary 显示Java堆详细信息;
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects 线下堆中对象的统计信息;
    -clstats             to print class loader statistics Java堆中内存的类加载器的统计信息;
    -finalizerinfo       to print information on objects awaiting finalization 显示在F-Queue队列等待Finlizer线程执行finalizer方法的对象
    -dump:<dump-options> to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=<file>  dump heap to <file>
                         Example: jmap -dump:live,format=b,file=heap.bin <pid>  生成堆转储快照;
    -F                   force. Use with -dump:<dump-options> <pid> or -histo
                         to force a heap dump or histogram when <pid> does not
                         respond. The "live" suboption is not supported
                         in this mode. 当-dump没有响应时,强制生成dump快照;
    -h | -help           to print this help message
    -J<flag>             to pass <flag> directly to the runtime system
  • jmap -dump:live,format=b,file=dump.hprof pid
    dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名。
  • jmap -heap pid
    打印heap的概要信息,GC使用的算法,heap的配置和使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况。
Attaching to process ID 11142, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.111-b14

using thread-local object allocation.
Parallel GC with 23 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 40 GC后如果发现空闲堆内存占到整个预估堆内存的N%(百分比), 则放大堆内存的预估最大值
   MaxHeapFreeRatio         = 70 GC后如果发现空闲堆内存占到整个预估堆内存的N%(百分比),则收缩堆内存的预估最大值, 预估堆内存是堆大小动态调控的重要选项之一. 堆内存预估最大值一定小于或等于固定最大值(-Xmx指定的数值). 前者会根据使用情况动态调大或缩小, 以提高GC回收的效率
   MaxHeapSize              = 8589934592 (8192.0MB) 即-Xmx, 堆内存大小的上限
   NewSize                  = 2147483648 (2048.0MB) 新生代预估堆内存占用的默认值
   MaxNewSize               = 2147483648 (2048.0MB) 新生代占整个堆内存的最大值
   OldSize                  = 3221225472 (3072.0MB) 老年代的默认大小
   NewRatio                 = 2 老年代对比新生代的空间大小, 比如2代表老年代空间是新生代的两倍大小
   SurvivorRatio            = 8 Eden/Survivor的值,但是survivor区有2个,故8代表eden:s1:s2=8:1:1
   MetaspaceSize            = 268435456 (256.0MB) 分配给类元数据空间的初始大小(Oracle逻辑存储上的初始高水位,the initial high-water-mark ). 此值为估计值. MetaspaceSize设置得过大会延长垃圾回收时间. 垃圾回收过后, 引起下一次垃圾回收的类元数据空间的大小可能会变大
   CompressedClassSpaceSize = 1073741824 (1024.0MB) 类指针压缩空间大小, 默认为1G
   MaxMetaspaceSize         = 536870912 (512.0MB) 是分配给类元数据空间的最大值, 超过此值就会触发Full GC. 此值仅受限于系统内存的大小, JVM会动态地改变此值
   G1HeapRegionSize         = 0 (0.0MB) G1区块的大小, 取值为1M至32M. 其取值是要根据最小Heap大小划分出2048个区块.

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 2110259200 (2012.5MB)
   used     = 876316224 (835.7202758789062MB)
   free     = 1233942976 (1176.7797241210938MB)
   41.52647333559783% used
From Space:
   capacity = 18874368 (18.0MB)
   used     = 14057488 (13.406265258789062MB)
   free     = 4816880 (4.5937347412109375MB)
   74.47925143771701% used
To Space:
   capacity = 18350080 (17.5MB)
   used     = 0 (0.0MB)
   free     = 18350080 (17.5MB)
   0.0% used
PS Old Generation
   capacity = 3221225472 (3072.0MB)
   used     = 2173077544 (2072.4082412719727MB)
   free     = 1048147928 (999.5917587280273MB)
   67.46120577057202% used

41844 interned Strings occupying 4768240 bytes.
  • jmap -finalizerinfo pid
    打印等待回收的对象信息。Number of objects pending for finalization:0 说明当前F-Queue队列中并没有等待Finalizer线程执行finalizer方法的对象。
Attaching to process ID 7692, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.91-b15
Number of objects pending for finalization: 0
  • jmap -histo:live pid
    打印堆的对象统计,包括对象数、内存大小等。jmap -histo:live这个命令执行,JVM会先触发gc,然后再统计信息。
    第一列:编号id
    第二列:实例个数
    第三列:所有实例大小
    第四列:类名
  • jmap -clstats pid
    打印Java类加载器的智能统计信息,对于每个类加载器而言,对于每个类加载器而言,它的名称,活跃度,地址,父类加载器,它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。

jhat

主要是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言。

Usage:  jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>

        -J<flag>          Pass <flag> directly to the runtime system. For
                          example, -J-mx512m to use a maximum heap size of 512MB -- 在启动JVM时传入一些启动参数,如果需要使用多个JVM启动参数,则传入多个-J<flag>
        -stack false:     Turn off tracking object allocation call stack. -- 关闭对象分配调用栈跟踪,如果分配位置信息在堆转储中不可用则必须将此标志设置为false,默认值为true
        -refs false:      Turn off tracking of references to objects -- 关闭对象引用跟踪,默认值为true,默认情况下,返回的指针是指向其他特定对象的对象,如反向链接或输入引用,会统计/计算堆中的所有对象
        -port <port>:     Set the port for the HTTP server.  Defaults to 7000 -- 设置jhat HTTP server端口号,默认值7000
        -exclude <file>:  Specify a file that lists data members that should 
                          be excluded from the reachableFrom query. -- 指定对象查询时需要排除的数据成员列表文件。例如,如果文件列列出了java.lang.String.value,那么当从某个特定对象Object o计算可达的对象列表时,引用路径涉及java.lang.String.value的都会被排除。
        -baseline <file>: Specify a baseline object dump.  Objects in
                          both heap dumps with the same ID and same class will
                          be marked as not being "new". -- 指定一个基准堆转储。在两个heap dumps中有相同object ID的对象会被标记为不是新的。其他对象被标记为新的。在比较两个不同的堆转储时很有用
        -debug <int>:     Set debug level.
                            0:  No debug output
                            1:  Debug hprof file parsing
                            2:  Debug hprof file parsing, no server -- 设置debug级别,0表示不输出调试信息,值越大则表示输出更详细的debug信息
        -version          Report version number
        -h|-help          Print this help and exit
        <file>            The file to read

For a dump file that contains multiple heap dumps,
you may specify which dump in the file
by appending "#" to the file name, i.e. "foo.hprof#3".

All boolean options default to "true"

jstat

用于监控虚拟机各种运行状态信息的命令行工具。他可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形的服务器上,它是运行期定位虚拟机性能问题的首选工具。

  • jstat -class pid 类加载统计
 [@c9db8f728f0d /opt/logs]$ jstat -class pid
Loaded  Bytes  Unloaded  Bytes     Time   
  9584 18833.9       56    81.6       6.75

Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间

  • jstat -gc pid 垃圾回收统计
 [@c9db8f728f0d /opt/logs]$ jstat -gc pid
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
117760.0 121344.0  0.0   79136.1 2007552.0 223811.3 4007936.0   146712.4  60312.0 59088.8 7168.0 6863.2     39    9.431   3      1.003   10.434

S0C:第一个幸存区的大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
OC:老年代大小
OU:老年代使用大小
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

  • jstat -gccapacity pid 堆内存分配
 [@c9db8f728f0d /opt/logs]$ jstat -gccapacity pid
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
2252800.0 2252800.0 2252800.0 117760.0 121344.0 2007552.0  4007936.0  4007936.0  4007936.0  4007936.0      0.0 1101824.0  60312.0      0.0 1048576.0   7168.0     39     3

NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数

  • jstat -gcutil pid 总结垃圾回收统计
 [@c9db8f728f0d /opt/logs]$ jstat -gcutil pid
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00  65.22  31.95   3.66  97.97  95.75     39    9.431     3    1.003   10.434

S0:幸存1区当前使用比例
S1:幸存2区当前使用比例
E:伊甸园区使用比例
O:老年代使用比例
M:元数据区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

  • jstat -gcnew pid 新生代垃圾回收统计
 [@c9db8f728f0d /opt/logs]$ jstat -gcnew pid
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
117760.0 121344.0    0.0 79136.1 15  15 117760.0 2007552.0 814895.2     39    9.431

S0C:第一个幸存区大小
S1C:第二个幸存区的大小
S0U:第一个幸存区的使用大小
S1U:第二个幸存区的使用大小
TT:对象在新生代存活的次数
MTT:对象在新生代存活的最大次数
DSS:期望的幸存区大小
EC:伊甸园区的大小
EU:伊甸园区的使用大小
YGC:年轻代垃圾回收次数

  • jstat -gcold pid 老年代垃圾回收统计
 [@c9db8f728f0d /opt/logs]$ jstat -gcold pid
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
 60312.0  59088.8   7168.0   6863.2   4007936.0    146712.4     39     3    1.003   10.434

MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
OC:老年代大小
OU:老年代使用大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

  • jstat -gcoldcapacity pid 老年代内存统计
 [@c9db8f728f0d /opt/logs]$ jstat -gcoldcapacity pid
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT   
  4007936.0   4007936.0   4007936.0   4007936.0    39     3    1.003   10.434

OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:老年代大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

  • jstat -gcmetacapacity pid 元数据空间内存统计
 [@c9db8f728f0d /opt/logs]$ jstat -gcmetacapacity 237
   MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT   
       0.0  1101824.0    60312.0        0.0  1048576.0     7168.0    39     3    1.003   10.434

MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代垃圾回收次数
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

  • jstat -gcnewcapacity 年轻代内存统计
[@c9db8f728f0d /opt/logs]$ jstat -gcnewcapacity 32417
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
  349184.0   698880.0   611328.0 232960.0  43520.0 232960.0  43520.0   697856.0   524288.0     2     0

NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0CMX:最大幸存1区大小
S0C:当前幸存1区大小
S1CMX:最大幸存2区大小
S1C:当前幸存2区大小
ECMX:最大伊甸园区大小
EC:当前伊甸园区大小
YGC:年轻代垃圾回收次数
FGC:老年代回收次数

jinfo

用来查看jvm的配置参数

Usage:
    jinfo [option] <pid>
        (to connect to running process) 
    jinfo [option] <executable <core>
        (to connect to a core file)
    jinfo [option] [server_id@]<remote server IP or hostname>
        (to connect to remote debug server)

where <option> is one of:
    -flag <name>         to print the value of the named VM flag
    -flag [+|-]<name>    to enable or disable the named VM flag
    -flag <name>=<value> to set the named VM flag to the given value
    -flags               to print VM flags
    -sysprops            to print Java system properties
    <no option>          to print both of the above
    -h | -help           to print this help message
  • jinfo -flag name pid 查看指定的 jvm 参数的值
$ jinfo -flag MetaspaceSize 22492
-XX:MetaspaceSize=67108864
  • jinfo -flag [+|-]name pid 开启或者关闭对应名称的参数,使用 jinfo 可以在不重启虚拟机的情况下,可以动态的修改 jvm 的参数。尤其在线上的环境特别有用。
$ jinfo -flag +PrintGC 22492
$ jinfo -flag -PrintGC 22492
  • jinfo -flag name=value pid 修改指定参数的值。但并不是所有的参数都支持动态修改
$ jinfo -flag HeapDumpPath=D:\JDK\Java\error.hprof 22492
  • jinfo -flags pid 输出全部的参数
  • jinfo -sysprops pid 输出当前 jvm 进行的全部的系统属性

jstack

获取当前进程的所有线程信息

Usage:
    jstack [-l] <pid>
        (to connect to running process)
    jstack -F [-m] [-l] <pid>
        (to connect to a hung process)
    jstack [-m] [-l] <executable> <core>
        (to connect to a core file)
    jstack [-m] [-l] [server_id@]<remote server IP or hostname>
        (to connect to a remote debug server)

Options:
    -F  to force a thread dump. Use when jstack <pid> does not respond (process is hung) -- 当’jstack [-l] pid’没有相应的时候强制打印栈信息
    -m  to print both java and native frames (mixed mode) -- 打印java和native c/c++框架的所有栈信息.
    -l  long listing. Prints additional information about locks -- 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent 的 ownable synchronizers列表.
    -h or -help to print this help message

每个线程堆中信息中,都可以查看到 线程ID、线程的状态(wait、sleep、running 等状态)、是否持有锁信息等
JVM调试工具_第1张图片

你可能感兴趣的:(JVM)