jstack、堆、GC的常用命令

anjingsi 1年前 ⋅ 1083 阅读

jstack、堆、GC的常用命令

如果是docker启动的服务,则需要先开启ptrace

而是 Docker 自 1.10 版本开始加入的安全特性。jmap 这类 JDK 工具依赖于 Linux 的 PTRACE_ATTACH,而 Docker 自 1.10 版本开始,默认的 seccomp 配置文件中禁用了 ptrace,如果不开启则会出现一下的错误

Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 6: Operation not permitted
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process: ptrace(PTRACE_ATTACH, ..) failed for 6: Operation not permitted

jstack

打印某个进程的堆栈信息

jstack [option] <pid>
选项含义
-F当正常输出的请求不被响应时,强制输出线程堆栈
-m如果调用到本地方法的话,可以显示C/C++的堆栈
-l除堆栈外,显示关于锁的附加信息,在发生死锁时可以用jstack -l pid来观察锁持有情况

输出某个进程的堆栈信息到文件中

jstack pid > filePath.tdump

堆信息

查看堆heap占用情况

root@5da1796872db:/# jps
7 jar
78 Jps
root@5da1796872db:/# jmap -heap pid
Attaching to process ID 7, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.342-b07

using thread-local object allocation.
Garbage-First (G1) GC with 4 thread(s)

Heap Configuration:     #堆内存初始化配置
   MinHeapFreeRatio         = 40     #-XX:MinHeapFreeRatio设置JVM堆最小空闲比率
   MaxHeapFreeRatio         = 70     #-XX:MaxHeapFreeRatio设置JVM堆最大空闲比率
   MaxHeapSize              = 12620660736 (12036.0MB)      #-XX:MaxHeapSize=设置JVM堆的最大大小
   NewSize                  = 1363144 (1.2999954223632812MB)      #-XX:NewSize=设置JVM堆的‘新生代’的默认大小
   MaxNewSize               = 7570718720 (7220.0MB)      #-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
   OldSize                  = 5452592 (5.1999969482421875MB)      #-XX:OldSize=设置JVM堆的‘老生代’的大小
   NewRatio                 = 2      #-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
   SurvivorRatio            = 8      #-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
   MetaspaceSize            = 21807104 (20.796875MB)      # metaspace,元数据空间,专门用来存元数据的,它是jdk8里特有的数据结构用来替代perm(永久代)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)      #-XX:CompressedClassSpaceSize=设置Klass Metaspace的大小
   MaxMetaspaceSize         = 17592186044415 MB      #用于设置metaspace区域的最大值,这个值可以通过mxbean中的MemoryPoolBean获取到,如果这个参数没有设置,那么就是通过mxbean拿到的最大值是-1,表示无穷大。
   G1HeapRegionSize         = 2097152 (2.0MB)      #-XX:G1HeapRegionSize=n,使用G1时Java堆会被分为大小统一的的区(region)。此参数可以指定每个heap区的大小. 默认值将根据 heap size 算出最优解. 最小值为 1Mb, 最大值为 32Mb.

Heap Usage: #堆使用
G1 Heap:
   regions  = 6018
   capacity = 12620660736 (12036.0MB)#总容量
   used     = 413138944 (394.0MB)#使用情况
   free     = 12207521792 (11642.0MB)#剩余容量
   3.2735127949484877% used
G1 Young Generation:
Eden Space: #Eden区内存分布
   regions  = 133
   capacity = 463470592 (442.0MB)
   used     = 278921216 (266.0MB)
   free     = 184549376 (176.0MB)
   60.18099547511312% used
Survivor Space:
   regions  = 17
   capacity = 35651584 (34.0MB)
   used     = 35651584 (34.0MB)
   free     = 0 (0.0MB)
   100.0% used
G1 Old Generation:
   regions  = 48
   capacity = 291504128 (278.0MB)
   used     = 98566144 (94.0MB)
   free     = 192937984 (184.0MB)
   33.81294964028777% used

37180 interned Strings occupying 3797384 bytes.

查看对象占用内存情况

root@5da1796872db:/# jmap -histo:live pid

 num     #instances         #bytes  class name
----------------------------------------------
   1:        459904       33413656  [C
   2:        459531       11028744  java.lang.String
   3:        159580        9371824  [Ljava.lang.Object;
   4:         66395        5842760  java.lang.reflect.Method
   5:        117564        4702560  java.util.LinkedHashMap$Entry
   6:        179720        4313280  java.util.ArrayList
   7:         17027        4310544  [B
   8:        122972        3935104  java.util.concurrent.ConcurrentHashMap$Node
   9:        201016        3216256  org.apache.ibatis.scripting.xmltags.StaticTextSqlNode
  10:         27718        2548264  [Ljava.util.HashMap$Node;
  11:         48242        2315616  org.aspectj.weaver.reflect.ShadowMatchImpl
  12:         96131        2307144  org.apache.ibatis.scripting.xmltags.IfSqlNode
  13:         33433        1872248  java.util.LinkedHashMap
  14:        116751        1868016  org.apache.ibatis.scripting.xmltags.MixedSqlNode
  15:         16306        1824360  java.lang.Class
  16:         97719        1563504  org.apache.ibatis.scripting.xmltags.ExpressionEvaluator
  17:         21490        1547280  java.lang.reflect.Field
  18:         48242        1543744  org.aspectj.weaver.patterns.ExposedState
  19:         37631        1204192  java.util.HashMap$Node
  20:           374        1055616  [Ljava.util.concurrent.ConcurrentHashMap$Node;
  21:         42278        1014672  java.util.Collections$UnmodifiableRandomAccessList
  22:         42587         946424  [Ljava.lang.Class;
  23:         17466         838368  java.util.HashMap
  24:          6770         649920  org.apache.ibatis.mapping.MappedStatement
  25:         12001         474064  [I
  26:         27212         435392  java.lang.Object
  ......
  5992:             1             16  top.doudou.mybatis.plus.druid.RemoveDruidAdConfig$1
  5993:             1             16  top.doudou.mybatis.plus.interceptor.MybatisInterceptor
  Total       2900421      117573528

输出内容部分说明

  • [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[]数组来保存数据的。

导出堆信息

root@5da1796872db:/# jmap -dump:live,format=b,file=fileName.dmp pid
Dumping heap to /fileName.dmp ...
Heap dump file created

GC

类加载统计

root@5da1796872db:/# jstat -class pid
Loaded  Bytes  Unloaded  Bytes     Time   
 15292 29156.0        0     0.0      11.70
表头LoadedBytesUnloadedBytesTime
含义加载class的数量所占用空间大小未加载数量未加载占用空间时间

编译统计

root@5da1796872db:/# jstat -compiler pid count
Compiled Failed Invalid   Time   FailedType FailedMethod
    9935      1       0    57.95          1 org/springframework/util/ReflectionUtils doWithMethods
表头CompiledFailedInvalidTimeFailedTypeFailedMethod
含义编译数量失败数量不可用数量时间失败类型失败的方法

垃圾回收统计

root@5da1796872db:/# jstat -gc pid 2000 2
S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
0.0    0.0    0.0    0.0   235520.0  2048.0   147456.0   114817.9  91508.0 87653.0 10952.0 10279.4     22    1.447   1      3.097    4.544
0.0    0.0    0.0    0.0   235520.0  2048.0   147456.0   114817.9  91508.0 87653.0 10952.0 10279.4     22    1.447   1      3.097    4.544

pid后面的2000表示2s,有这个参数则是,每隔2s返回一次数据,没有则只是查询当时数据,最后一个参数表示采样数目

末尾为C,代表该区Capacity(容量)

末尾为U,代表Used(已使用的容量)

表头S0CS1CS0US1UECEUOCOUMCMUYGCYGCTFGCFGCT
含义Survive0 第一个幸存区的容量大小Survive1 第二个幸存区的容量大小Survive0 第一个幸存区已使用的内存大小Survive1 第二个幸存区已使用的内存大小Eden 伊甸园区的容量大小Eden 伊甸园区已使用的内存大小Old 老年代的容量大小Old 老年代已使用的内存大小Meta 方法区的容量大小Meta 方法区已使用的内存大小Young GC发生的次数Young GC的总耗时Full GC发生的次数Full GC的总耗时

堆内存统计

root@5da1796872db:/# jstat -gccapacity 7 2000 2
NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC 
0.0 12324864.0 235520.0    0.0    0.0 235520.0        0.0 12324864.0   147456.0   147456.0      0.0 1130496.0  91508.0      0.0 1048576.0  10952.0     22     1
0.0 12324864.0 235520.0    0.0    0.0 235520.0        0.0 12324864.0   147456.0   147456.0      0.0 1130496.0  91508.0      0.0 1048576.0  10952.0     22     1
表头NGCMNNGCMXNGCS0CS1CECOGCMNOGCMXOGCOCMCMNMCMXMCCCSMNCCSMXCCSCYGCFGC
含义新生代最小容量新生代最大容量当前新生代容量第一个幸存区大小第二个幸存区的大小伊甸园区的大小老年代最小容量老年代最大容量当前老年代大小当前老年代大小最小元数据容量最大元数据容量当前元数据空间大小最小压缩类空间大小最大压缩类空间大小当前压缩类空间大小年轻代gc次数老年代GC次数

新生代垃圾回收统计

root@5da1796872db:/# jstat -gcnew 7 2000 2
S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT  
0.0    0.0    0.0    0.0  6  15 29696.0 235520.0   2048.0     22    1.447
0.0    0.0    0.0    0.0  6  15 29696.0 235520.0   2048.0     22    1.447

表头S0CS1CS0US1UTTMTTDSSECEUYGCYGCT
含义第一个幸存区大小第二个幸存区的大小第一个幸存区的使用大小第二个幸存区的使用大小对象在新生代存活的次数对象在新生代存活的最大次数期望的幸存区大小伊甸园区的大小伊甸园区的使用大小年轻代垃圾回收次数年轻代垃圾回收消耗时间

新生代内存统计

root@5da1796872db:/# jstat -gcnewcapacity 7 2000 2
NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC 
0.0 12324864.0   235520.0      0.0      0.0 12324864.0      0.0 12324864.0   235520.0    22     1
0.0 12324864.0   235520.0      0.0      0.0 12324864.0      0.0 12324864.0   235520.0    22     1

表头NGCMNNGCMXNGCS0CMXS0CS1CMXS1CECMXECYGCFGC
含义新生代最小容量新生代最大容量当前新生代容量最大幸存1区大小当前幸存1区大小最大幸存2区大小当前幸存2区大小最大伊甸园区大小当前伊甸园区大小年轻代垃圾回收次数老年代回收次数

老年代垃圾回收统计

root@b163e5a030ff:/# jstat -gcold 7 2000 2
  MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT   
87808.0  83909.2  10496.0   9793.6    284672.0     94208.0     22     0    0.000    1.047
87808.0  83909.2  10496.0   9793.6    284672.0     94208.0     22     0    0.000    1.047

表头MCMUCCSCCCSUOCOUYGCFGCFGCTGCT
含义方法区大小方法区使用大小压缩类空间大小压缩类空间使用大小老年代大小老年代使用大小年轻代垃圾回收次数老年代垃圾回收次数老年代垃圾回收消耗时间垃圾回收消耗总时间

老年代内存统计

root@b163e5a030ff:/# jstat -gcoldcapacity 7 2000 2
OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT   
0.0  12324864.0    284672.0    284672.0    22     0    0.000    1.047
0.0  12324864.0    284672.0    284672.0    22     0    0.000    1.047
表头OGCMNOGCMXOGCOCYGCFGCFGCTGCT
含义老年代最小容量老年代最大容量当前老年代大小老年代大小年轻代垃圾回收次数老年代垃圾回收次数老年代垃圾回收消耗时间垃圾回收消耗总时间

元数据空间统计

root@b163e5a030ff:/# jstat -gcmetacapacity 7 2000 2
MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT   
0.0  1126400.0    87808.0        0.0  1048576.0    10496.0    22     0    0.000    1.047
0.0  1126400.0    87808.0        0.0  1048576.0    10496.0    22     0    0.000    1.047
表头MCMNMCMXMCCCSMNCCSMXCCSCYGCFGCFGCTGCT
含义最小元数据容量最大元数据容量当前元数据空间大小最小压缩类空间大小最大压缩类空间大小当前压缩类空间大小年轻代垃圾回收次数老年代垃圾回收次数老年代垃圾回收消耗时间垃圾回收消耗总时间

总结垃圾回收统计

root@b163e5a030ff:/# jstat -gcutil 7 2000 2
S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
0.00 100.00  53.64  33.09  95.56  93.31     22    1.047     0    0.000    1.047
0.00 100.00  53.64  33.09  95.56  93.31     22    1.047     0    0.000    1.047
表头S0S1EOMCCSYGCFGCFGCTGCT
含义幸存1区当前使用比例幸存2区当前使用比例伊甸园区使用比例老年代使用比例元数据区使用比例压缩使用比例年轻代垃圾回收次数老年代垃圾回收次数老年代垃圾回收消耗时间垃圾回收消耗总时间

JVM编译方法统计

root@b163e5a030ff:/# jstat -printcompilation 7 2000 2
Compiled  Size  Type Method
10763   1652    1 org/springframework/cloud/openfeign/clientconfig/HttpClientFeignConfiguration$1 run
10763   1652    1 org/springframework/cloud/openfeign/clientconfig/HttpClientFeignConfiguration$1 run
表头CompiledSizeTypeMethod
含义最近编译方法的数量最近编译方法的字节码数量最近编译方法的编译类型方法名标识

docker设置G1垃圾回收器参数

以下任意一种方式即可

dockerfile的方式

......
ENV JAVA_OPTS=" -server -XX:SurvivorRatio=8 -XX:+DisableExplicitGC \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=100 -XX:SoftRefLRUPolicyMSPerMB=1000 -XX:+HeapDumpOnOutOfMemoryError \
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms512m -Xmx1024m \
-XX:NewRatio=3 -XX:+PrintGC -XX:+PrintGCDetails \
-XX:+PrintTenuringDistribution -XX:+PrintGCTimeStamps -XX:+PrintCommandLineFlags"
ENTRYPOINT java ${JAVA_OPTS} -Dspring.profiles.active=test -Djava.security.egd=file:/dev/./urandom -jar /app.jar

Docker Compose的方式

version: "3.5"
services:
  xxx-server: 
    image: xxx
    environment:
      - JAVA_OPTS=-Xmx30m -Xms512m -Xss1024k

常用的几个参数设置

  • -Xms512m:设置JVM初始堆内存为512m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
  • -Xmx1024m:设置JVM最大堆内存为1024m。
  • -Xss1024k:设置每个线程的栈大小。JDK5.0以后每个线程栈大小为1M,之前每个线程栈大小为256K。应当根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。需要注意的是:当这个值被设置的较大(例如>2MB)时将会在很大程度上降低系统的性能。
  • -Xmn2g:设置年轻代大小为2G。在整个堆内存大小确定的情况下,增大年轻代将会减小年老代,反之亦然。此值关系到JVM垃圾回收,对系统性能影响较大,官方推荐配置为整个堆大小的3/8。
  • -XX:NewSize=1024m:设置年轻代初始值为1024M。
  • -XX:MaxNewSize=1024m:设置年轻代最大值为1024M。
  • -XX:PermSize=256m:设置持久代初始值为256M。
  • -XX:MaxPermSize=256m:设置持久代最大值为256M。
  • -XX:NewRatio=4:设置年轻代(包括1个Eden和2个Survivor区)与年老代的比值。表示年轻代比年老代为1:4。
  • -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的比值。表示2个Survivor区(JVM堆内存年轻代中默认有2个大小相等的Survivor区)与1个Eden区的比值为2:4,即1个Survivor区占整个年轻代大小的1/6。
  • -XX:MaxTenuringThreshold=7:表示一个对象如果在Survivor区(救助空间)移动了7次还没有被垃圾回收就进入年老代。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代,对于需要大量常驻内存的应用,这样做可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代存活时间,增加对象在年轻代被垃圾回收的概率,减少Full GC的频率,这样做可以在某种程度上提高服务稳定性。

查看java的默认垃圾收集器

C:\Users\anjingsi>java -XX:+PrintCommandLineFlags -version
-XX:G1ConcRefinementThreads=10 -XX:GCDrainStackTargetSize=64 -XX:InitialHeapSize=265781120 -XX:MaxHeapSize=4252497920 -XX:MinHeapSize=6815736 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation
java version "14.0.2" 2020-07-14
Java(TM) SE Runtime Environment (build 14.0.2+12-46)
Java HotSpot(TM) 64-Bit Server VM (build 14.0.2+12-46, mixed mode, sharing)

查看jvm的垃圾收集器

root@5da1796872db:/# jmap -heap pid
Attaching to process ID 7, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.342-b07

using thread-local object allocation.
Garbage-First *(G1) GC* with 4 thread(s)

docker开启ptrace

官网链接:https://docs.docker.com/engine/reference/run/

方式一

关闭seccomp,在启动容器时添加参数–security-opt seccomp=unconfined

docker run --security-opt seccomp:unconfined ...

方式二

启动容器时添加参数–cap-add=SYS_PTRACE

docker run --cap-add=SYS_PTRACE ...

Docker Compose的更改方式

version: "3.5"
services:
  xxx-server: 
    image: xxx
    cap_add:
      - SYS_PTRACE
    ......

全部评论: 0

    我有话说: