jmap和jstat

概述

jmap命令有下面几种常用的用法:

•jmap [pid]

•jmap -histo:live [pid] >a.log

•jmap -dump:live,format=b,file=xxx.xxx [pid]

用得最多是后面两个。其中,jmap -histo:live [pid] 可以查看当前Java进程创建的活跃对象数目和占用内存大小。

jmap -dump:live,format=b,file=xxx.xxx [pid] 则可以将当前Java进程的内存占用情况导出来,方便用专门的内存分析工具(例如:MAT)来分析。


jmap -heap <pid>输出

[tomcat@n01 ~]$ /opt/java/jdk1.8.0_101/bin/jmap -heap 11368   
Attaching to process ID 11368, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.101-b13

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

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 2684354560 (2560.0MB)
   NewSize                  = 1073741824 (1024.0MB)
   MaxNewSize               = 1073741824 (1024.0MB)
   OldSize                  = 1610612736 (1536.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 852492288 (813.0MB)
   used     = 420427144 (400.95056915283203MB)
   free     = 432065144 (412.04943084716797MB)
   49.31741317993014% used
From Space:
   capacity = 113770496 (108.5MB)
   used     = 2299712 (2.19317626953125MB)
   free     = 111470784 (106.30682373046875MB)
   2.021360617079493% used
To Space:
   capacity = 107479040 (102.5MB)
   used     = 0 (0.0MB)
   free     = 107479040 (102.5MB)
   0.0% used
PS Old Generation
   capacity = 1610612736 (1536.0MB)
   used     = 50883368 (48.526161193847656MB)
   free     = 1559729368 (1487.4738388061523MB)
   3.1592552860577903% used
interned Strings occupying 3138384 bytes.

MaxHeapFreeRatio: GC后如果发现空闲堆内存占到整个预估堆内存的N%(百分比),则收缩堆内存的预估最大值, 预估堆内存是堆大小动态调控的重要选项之一. 堆内存预估最大值一定小于或等于固定最大值(-Xmx指定的数值). 前者会根据使用情况动态调大或缩小, 以提高GC回收的效率
MinHeapFreeRatio: GC后如果发现空闲堆内存占到整个预估堆内存的N%(百分比), 则放大堆内存的预估最大值

MaxHeapSize: 即-Xmx, 堆内存大小的上限
InitialHeapSize: 即-Xms, 堆内存大小的初始值

NewSize: 新生代预估堆内存占用的默认值
MaxNewSize: 新生代占整个堆内存的最大值

OldSize: 老年代的默认大小, default size of the tenured generation
NewRatio: 老年代对比新生代的空间大小, 比如2代表老年代空间是新生代的两倍大小. The ratio of old generation to young generation.

SurvivorRatio: Eden/Survivor的值. 这个值的说明, 很多网上转载的都是错的. 8表示Survivor:Eden=1:8, 因为survivor区有2个, 所以Eden的占比为8/10. Ratio of eden/survivor space size. -XX:SurvivorRatio=6 sets the ratio between each survivor space and eden to be 1:6, each survivor space will be one eighth of the young generation. 
 

xxxRatio一般以xxx作为分母,NewRatio是Old:New,SurvivorRatio是Eden:Survivor

Eden:Survivor = 8: 1  

Old: New = 2:1 

MetaspaceSize: 分配给类元数据空间的初始大小(Oracle逻辑存储上的初始高水位,the initial high-water-mark ). 此值为估计值. MetaspaceSize设置得过大会延长垃圾回收时间. 垃圾回收过后, 引起下一次垃圾回收的类元数据空间的大小可能会变大
MaxMetaspaceSize: 是分配给类元数据空间的最大值, 超过此值就会触发Full GC. 此值仅受限于系统内存的大小, JVM会动态地改变此值

CompressedClassSpaceSize: 类指针压缩空间大小, 默认为1G

G1HeapRegionSize: G1区块的大小, 取值为1M至32M. 其取值是要根据最小Heap大小划分出2048个区块. With G1 the Java heap is subdivided into uniformly sized regions. This sets the size of the individual sub-divisions. The default value of this parameter is determined ergonomically based upon heap size. The minimum value is 1Mb and the maximum value is 32Mb. Sets the size of a G1 region. The value will be a power of two and can range from 1MB to 32MB. The goal is to have around 2048 regions based on the minimum Java heap size.
 

指针压缩1. 64位平台上默认打开
  1)使用-XX:+UseCompressedOops压缩对象指针
    "oops"指的是普通对象指针("ordinary" object pointers)。
    Java堆中对象指针会被压缩成32位。
    使用堆基地址(如果堆在低26G内存中的话,基地址为0)
  2)使用-XX:+UseCompressedClassPointers选项来压缩类指针
    对象中指向类元数据的指针会被压缩成32位
    类指针压缩空间会有一个基地址

2. 元空间和类指针压缩空间的区别
  1)类指针压缩空间只包含类的元数据,比如InstanceKlass, ArrayKlass
    仅当打开了UseCompressedClassPointers选项才生效
    为了提高性能,Java中的虚方法表也存放到这里
    这里到底存放哪些元数据的类型,目前仍在减少
  2)元空间包含类的其它比较大的元数据,比如方法,字节码,常量池等。

使用  jmap -heap pid ,可以查看各个代的内存使用情况。

$ jmap -heap 2083

  可以观察到New Generation(Eden Space,From Space,To Space),tenured generation,Perm Generation的内存使用情况

 

$ jmap -dump:format=b,file=heapdump.hprof <pid>

  导出heap dump到文件heapdump.hprof

  然后利用MAT工具分析是否存在内存泄漏等等  

$ jmap -histo:live 2083 | head -n 100

   可以观察heap中前100个占用内存最大的对象的情况(heap中所有生存的对象的情况)。包括对象数量和所占空间大小。

 

jmap -histo:live 2083 | head -n 100

[hadoop@DEV logs]$ jmap -histo 24527 | head -30

 num     #instances         #bytes  class name
----------------------------------------------
   1:         31939       98883072  [C
   2:          8594        9461992  [B
   3:         30326        4256232  <constMethodKlass>
   4:         30326        3892592  <methodKlass>
   5:          2719        3226344  <constantPoolKlass>
   6:          2450        1948704  <constantPoolCacheKlass>
   7:          2719        1869200  <instanceKlassKlass>
   8:         27599         662376  java.lang.String
   9:           836         442968  <methodDataKlass>
  10:          8215         394320  org.apache.tomcat.util.buf.ByteChunk
  11:          3012         366720  java.lang.Class
  12:         11257         360224  java.util.HashMap$Entry
  13:          3417         273360  java.lang.reflect.Method
  14:          6763         270520  java.util.TreeMap$Entry
  15:          4326         260720  [S
  16:          5410         259680  org.apache.tomcat.util.buf.MessageBytes
  17:          6410         256400  org.apache.tomcat.util.buf.CharChunk
  18:          4558         238352  [[I
  19:          3347         211512  [Ljava.lang.Object;
  20:          2144         189280  [I
  21:           276         147936  <objArrayKlassKlass>
  22:           948         142216  [Ljava.util.HashMap$Entry;
  23:          2874         137952  java.util.HashMap
  24:           621          89424  java.text.DecimalFormat
  25:          2555          81760  java.util.concurrent.ConcurrentHashMap$HashEntry
  26:           620          69440  java.util.GregorianCalendar
  27:          1052          68936  [Ljava.lang.String;

其中:

[C is a char[]
[S is a short[]
[I is a int[]
[B is a byte[]
[[I is a int[][]

上面的输出中[C对象占用Heap这么多,往往跟String有关,String其内部使用final char[]数组来保存数据的。

 

 

jstat查看 gc实时执行情况

jstat命令命令格式:

jstat [Options] vmid [interval] [count]

 

命令参数说明:

Options,一般使用 -gcutil 或  -gc 查看gc 情况

pid,当前运行的 java进程号 
interval,间隔时间,单位为秒或者毫秒 
count,打印次数,如果缺省则打印无数次

 

Options 参数如下:

-gc:统计 jdk gc时 heap信息,以使用空间字节数表示

-gcutil:统计 gc时, heap情况,以使用空间的百分比表示

-class:统计 class loader行为信息

-compile:统计编译行为信息

-gccapacity:统计不同 generations(新生代,老年代,持久代)的 heap容量情况

-gccause:统计引起 gc的事件

-gcnew:统计 gc时,新生代的情况

-gcnewcapacity:统计 gc时,新生代 heap容量

-gcold:统计 gc时,老年代的情况

-gcoldcapacity:统计 gc时,老年代 heap容量

-gcpermcapacity:统计 gc时, permanent区 heap容量

 

示例 

  $ jstat -gc 12538 5000

每5 秒一次显示进程号为 12538的 java进成的 GC情况,结果如下图:

 

jstat -gcutil 70129  1000

 由上图可知,新生代和老年代使用空间百分比接近100%,使用空间已经爆满了。

结果说明

标志

说明

S0C

年轻代中第一个survivor区的容量 (字节)

S1C

年轻代中第二个survivor区的容量 (字节)

S0U

年轻代中第一个survivor区目前已使用空间 (字节)

S1U

年轻代中第二个survivor区目前已使用空间 (字节)

EC

年轻代中Eden的容量 (字节)

EU

年轻代中Eden目前已使用空间 (字节)

OC

Old代的容量 (字节)

OU

Old代目前已使用空间 (字节)

PC

Perm(持久代)的容量 (字节)

PU

Perm(持久代)目前已使用空间 (字节)

YGC

从应用程序启动到采样时年轻代中gc次数

YGCT

从应用程序启动到采样时年轻代中gc所用时间(s)

FGC

从应用程序启动到采样时old代(全gc)gc次数

FGCT

从应用程序启动到采样时old代(全gc)gc所用时间(s)

GCT

从应用程序启动到采样时gc用的总时间(s)

NGCMN

年轻代(young)中初始化(最小)的大小 (字节)

NGCMX

年轻代(young)的最大容量 (字节)

NGC

年轻代(young)中当前的容量 (字节)

OGCMN

old代中初始化(最小)的大小 (字节)

OGCMX

old代的最大容量 (字节)

OGC

old代当前新生成的容量 (字节)

PGCMN

perm代中初始化(最小)的大小 (字节)

PGCMX

perm代的最大容量 (字节)  

PGC

perm代当前新生成的容量 (字节)

S0

年轻代中第一个survivor区已使用的占当前容量百分比

S1

年轻代中第二个survivor区已使用的占当前容量百分比

E

年轻代中Eden已使用的占当前容量百分比

O

old代已使用的占当前容量百分比

P

perm代已使用的占当前容量百分比

Mjdk1.8 metaspace已使用的占当前容量百分比

S0CMX

年轻代中第一个survivor区的最大容量 (字节)

S1CMX

年轻代中第二个survivor区的最大容量 (字节)

ECMX

年轻代中Eden的最大容量 (字节)

DSS

当前需要survivor区的容量 (字节)(Eden区已满)

TT

持有次数限制

MTT

最大持有次数限制

 转载自:jmap输出

Java JVM- jstat查看jvm的GC情况

jmap -histo pid 输出的[C [B [I [S methodKlass constantPoolKlass含义

Java线上应用故障排查之二:高内存占用

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值