JVM调优

本文详细介绍了JVM调优的各种工具,包括Jmap、Jstack、Jinfo、Jstat的使用,如Jmap的-histo和-heap选项用于内存分析,Jstack用于排查死锁和CPU占用高的线程,Jstat则用于监控垃圾回收和内存使用。通过这些工具,可以评估JVM的运行情况,例如年轻代对象增长速率、GC频率和耗时,并据此制定优化策略,降低Full GC对性能的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Jmap

Jmap -histo pid

当服务器内存占用飙高,可以使用Jmap查看Java应用内存信息,实例个数以及占用内存大小。

/**
* 测试代码
*/
public class HeapTest {

    private static List<Company> list = new ArrayList<>();

    public static void main(String[] args) {
        while (true){
            list.add(new Company());
        }
    }
}


class Company{

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

[root@master ~]# jmap -histo 260613

 num     #instances         #bytes  class name
----------------------------------------------
   1:      70091071     1121457136  com.jvm.Company
   2:           513      280390104  [Ljava.lang.Object;
   3:           882          84064  [C
   4:           471          54216  java.lang.Class
   5:             9          25040  [B
   6:           869          20856  java.lang.String
   7:           256           4096  java.lang.Integer
   8:            91           3640  java.lang.ref.SoftReference
   9:           109           3488  java.util.Hashtable$Entry
  10:            89           3000  [I
  11:             7           2632  java.lang.Thread
  12:            58           2024  [Ljava.lang.String;
  13:            38           1824  sun.util.locale.LocaleObjectCache$CacheEntry
  14:            51           1632  java.util.concurrent.ConcurrentHashMap$Node
  15:            19           1216  java.net.URL
  16:             2           1064  [Ljava.lang.invoke.MethodHandle;
  17:             1           1040  [Ljava.lang.Integer;
  18:            26           1040  java.io.ObjectStreamField


jmap -histo:live pid #查看当前存活的实例

当发生内存溢出时,可以根据GC日志找到问题代码。

[root@master ext]# java -XX:+PrintGCDetails com.jvm.HeapTest
[GC (Allocation Failure) [PSYoungGen: 31232K->5116K(36352K)] 31232K->21036K(119808K), 0.0260969 secs] [Times: user=0.07 sys=0.01, real=0.03 secs] 
[GC (Allocation Failure) [PSYoungGen: 36348K->5104K(67584K)] 52268K->40435K(151040K), 0.0301175 secs] [Times: user=0.08 sys=0.01, real=0.03 secs] 
[GC (Allocation Failure) [PSYoungGen: 55880K->5104K(67584K)] 91211K->107276K(170496K), 0.1080058 secs] [Times: user=0.15 sys=0.08, real=0.11 secs] 
[Full GC (Ergonomics) [PSYoungGen: 5104K->0K(67584K)] [ParOldGen: 102172K->80415K(205312K)] 107276K->80415K(272896K), [Metaspace: 2959K->2959K(1056768K)], 0.9571864 secs] [Times: user=2.76 sys=0.07, real=0.96 secs] 
[GC (Allocation Failure) [PSYoungGen: 62464K->5120K(100864K)] 178934K->154966K(306176K), 0.1663656 secs] [Times: user=0.58 sys=0.02, real=0.17 secs] 
[Full GC (Ergonomics) [PSYoungGen: 5120K->0K(100864K)] [ParOldGen: 149846K->138855K(305664K)] 154966K->138855K(406528K), [Metaspace: 2959K->2959K(1056768K)], 1.2778122 secs] [Times: user=4.28 sys=0.01, real=1.27 secs] 
[GC (Allocation Failure) [PSYoungGen: 95744K->5120K(130048K)] 288682K->288874K(435712K), 0.2113250 secs] [Times: user=0.77 sys=0.05, real=0.22 secs] 
[Full GC (Ergonomics) [PSYoungGen: 5120K->0K(130048K)] [ParOldGen: 283754K->252595K(510464K)] 288874K->252595K(640512K), [Metaspace: 2959K->2959K(1056768K)], 2.3398999 secs] [Times: user=6.97 sys=0.01, real=2.34 secs] 
[GC (Allocation Failure) [PSYoungGen: 124928K->98787K(201728K)] 377523K->377591K(712192K), 0.1152322 secs] [Times: user=0.40 sys=0.03, real=0.11 secs] 
[GC (Allocation Failure) [PSYoungGen: 201699K->120672K(236032K)] 602189K->521161K(746496K), 0.2797464 secs] [Times: user=1.02 sys=0.03, real=0.28 secs] 
[GC (Allocation Failure) [PSYoungGen: 223584K->152576K(245760K)] 624073K->624217K(756224K), 0.5179186 secs] [Times: user=1.98 sys=0.07, real=0.52 secs] 
[Full GC (Ergonomics) [PSYoungGen: 152576K->59363K(245760K)] [ParOldGen: 471641K->510462K(857088K)] 624217K->569825K(1102848K), [Metaspace: 2959K->2959K(1056768K)], 5.3441450 secs] [Times: user=16.13 sys=0.01, real=5.34 secs] 
[GC (Allocation Failure) [PSYoungGen: 152547K->152704K(303104K)] 845537K->845694K(1160192K), 0.3155097 secs] [Times: user=1.15 sys=0.04, real=0.31 secs] 
[GC (Allocation Failure) [PSYoungGen: 245888K->221696K(340480K)] 938878K->938918K(1197568K), 0.4408531 secs] [Times: user=1.67 sys=0.08, real=0.44 secs] 
[GC (Allocation Failure) [PSYoungGen: 340480K->221696K(340480K)] 1331496K->1331696K(1471488K), 0.6061501 secs] [Times: user=2.19 sys=0.13, real=0.61 secs] 
[Full GC (Ergonomics) [PSYoungGen: 221696K->0K(340480K)] [ParOldGen: 1110000K->1027081K(1332736K)] 1331696K->1027081K(1673216K), [Metaspace: 2959K->2959K(1056768K)], 8.5374366 secs] [Times: user=25.74 sys=0.01, real=8.53 secs] 
[GC (Allocation Failure) [PSYoungGen: 118784K->118880K(364544K)] 1145865K->1145961K(1697280K), 0.2941721 secs] [Times: user=1.16 sys=0.01, real=0.30 secs] 
[GC (Allocation Failure) [PSYoungGen: 272992K->154240K(375808K)] 1300073K->1300345K(1708544K), 0.6918694 secs] [Times: user=2.65 sys=0.04, real=0.69 secs] 
[GC (Allocation Failure) [PSYoungGen: 225119K->69344K(432128K)] 1371224K->1369881K(1764864K), 0.6465283 secs] [Times: user=2.43 sys=0.14, real=0.65 secs] 
[Full GC (Ergonomics) [PSYoungGen: 69344K->36499K(432128K)] [ParOldGen: 1300537K->1332728K(1332736K)] 1369881K->1369227K(1764864K), [Metaspace: 2959K->2959K(1056768K)], 11.4042660 secs] [Times: user=43.38 sys=0.01, real=11.40 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 36499K->36499K(432128K)] [ParOldGen: 1332728K->1332716K(1332736K)] 1369227K->1369216K(1764864K), [Metaspace: 2959K->2959K(1056768K)], 9.7899248 secs] [Times: user=37.66 sys=0.00, real=9.79 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:3210)
        at java.util.Arrays.copyOf(Arrays.java:3181)
        at java.util.ArrayList.grow(ArrayList.java:267)
        at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:241)
        at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:233)
        at java.util.ArrayList.add(ArrayList.java:464)
        at com.jvm.HeapTest.main(HeapTest.java:17)
Heap
 PSYoungGen      total 432128K, used 44916K [0x00000000d7580000, 0x00000000ffc00000, 0x0000000100000000)
  eden space 210432K, 3% used [0x00000000d7580000,0x00000000d7db83a8,0x00000000e4300000)
  from space 221696K, 16% used [0x00000000f1b80000,0x00000000f3f24f90,0x00000000ff400000)
  to   space 221696K, 0% used [0x00000000e4300000,0x00000000e4300000,0x00000000f1b80000)
 ParOldGen       total 1332736K, used 1332716K [0x0000000086000000, 0x00000000d7580000, 0x00000000d7580000)
  object space 1332736K, 99% used [0x0000000086000000,0x00000000d757b248,0x00000000d7580000)
 Metaspace       used 2996K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 282K, capacity 386K, committed 512K, reserved 1048576K

  • num:序号
  • instances:实例数量
  • bytes:占用空间大小
  • class name:类名称,[C is a char[],[S is a short[],[I is a int[],[B is a byte[],[[I is a int[][]

Jmap -heap pid

jmap -heap pid #查看堆内存信息

C:\Users\jay>jmap -heap 12748
Attaching to process ID 12748, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.261-b12

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

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 8573157376 (8176.0MB)
   NewSize                  = 178782208 (170.5MB)
   MaxNewSize               = 2857369600 (2725.0MB)
   OldSize                  = 358088704 (341.5MB)
   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 = 220200960 (210.0MB)
   used     = 5190456 (4.950004577636719MB)
   free     = 215010504 (205.04999542236328MB)
   2.357145036969866% used
From Space:
   capacity = 13107200 (12.5MB)
   used     = 0 (0.0MB)
   free     = 13107200 (12.5MB)
   0.0% used
To Space:
   capacity = 22020096 (21.0MB)
   used     = 0 (0.0MB)
   free     = 22020096 (21.0MB)
   0.0% used
PS Old Generation
   capacity = 222298112 (212.0MB)
   used     = 16611120 (15.841598510742188MB)
   free     = 205686992 (196.1584014892578MB)
   7.472452127708579% used

15765 interned Strings occupying 2109464 bytes.


jmap -dump:format=b,file=heap.hprof pid #导出堆内存信息

#设置内存溢出时自动导出dump文件:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=./   #指定路径
-XX:+PrintGCDetails 打印GC日志

Jstack

使用Jstack可以查找Java应用中是否存在死锁。

jstack pid

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x000002173b5f95d8 (object 0x0000000715d09a30, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x000002173b5f6d48 (object 0x0000000715d09a40, a java.lang.Object),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.jvm.DeadLockTest.lambda$main$1(DeadLockTest.java:35)
        - waiting to lock <0x0000000715d09a30> (a java.lang.Object)
        - locked <0x0000000715d09a40> (a java.lang.Object)
        at com.jvm.DeadLockTest$$Lambda$2/1225358173.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
"Thread-0":
        at com.jvm.DeadLockTest.lambda$main$0(DeadLockTest.java:22)
        - waiting to lock <0x0000000715d09a40> (a java.lang.Object)
        - locked <0x0000000715d09a30> (a java.lang.Object)
        at com.jvm.DeadLockTest$$Lambda$1/1587487668.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

预防死锁的发生

  1. 使用多个锁,设计锁的获取顺序,图形化表示出来;
  2. 使用可以设定超时时间的锁,比如ReentrantLock.tryLock(long timeout, TimeUnit unit)方法

使用Jstack找出占用CPU最高的线程堆栈信息

  1. 使用top -p 257949,显示Java进程的内存、CPU使用情况;

    [root@master ~]# top -p 257949
    top - 00:09:27 up 47 days, 15:42,  4 users,  load average: 0.87, 0.34, 0.16
    Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
    %Cpu(s): 25.7 us,  0.6 sy,  0.0 ni, 73.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem :  7990068 total,  3953816 free,  1776852 used,  2259400 buff/cache
    KiB Swap:        0 total,        0 free,        0 used.  5799316 avail Mem 
    
        PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND       
     257949 root      20   0 4486708  22100  11060 S 100.0  0.3   1:56.99 java  
    
  2. 按H,获取每个线程的内存情况;

    
        PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                   
     257950 root      20   0 4486708  22100  11060 R 99.9  0.3   3:37.19 java                      
     257949 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 java                      
     257951 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 java                      
     257952 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 java                      
     257953 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 java                      
     257954 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 java                      
     257955 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 VM Thread                 
     257956 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 Reference Handl           
     257957 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 Finalizer                 
     257958 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 Signal Dispatch           
     257959 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 C2 CompilerThre           
     257960 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.01 C2 CompilerThre           
     257961 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 C1 CompilerThre           
     257962 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.00 Service Thread            
     257963 root      20   0 4486708  22100  11060 S  0.0  0.3   0:00.12 VM Periodic Tas           
    
    
  3. 找到内存和CPU占用最高的线程tid 257950;

  4. 转为十六进制得到nid 3ef9e,此线程id的十六进制表示;

  5. jstack pid | grep -A 20 nid 从堆栈中找到导致CPU飙高的调用方法;

    [root@master ~]# jstack 257949 | grep -A 20 3ef9e
    "main" #1 prio=5 os_prio=0 tid=0x00007fe9f404b800 nid=0x3ef9e runnable [0x00007fe9fe46c000]
       java.lang.Thread.State: RUNNABLE
            at com.jvm.JVMTest.main(JVMTest.java:38)
    
    "VM Thread" os_prio=0 tid=0x00007fe9f40d6000 nid=0x3efa3 runnable 
    "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fe9f405e000 nid=0x3ef9f runnable 
    "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fe9f4060000 nid=0x3efa0 runnable 
    "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007fe9f4062000 nid=0x3efa1 runnable 
    "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fe9f4063800 nid=0x3efa2 runnable 
    "VM Periodic Task Thread" os_prio=0 tid=0x00007fe9f4131000 nid=0x3efab waiting on condition 
    
    JNI global references: 5
    
  6. 查看对应的堆栈信息找出可能存在问题的代码;

    找到com.jvm.JVMTest.main(JVMTest.java:38)

Jinfo

Jinfo可以查看正在运行的Java应用程序的参数,比如查看Java系统参数:
jinfo -sysprops pid

Jstat

Jstat可以查看堆内存各部分的使用量,以及加载类的数量。

#命令格式:
jstat [-命令选项]<vmid>[间隔时间毫秒][查询次数]

垃圾回收统计

jstat -gc pid,评估应用内存使用及GC压力整体情况

C:\Users\jay>jstat -gc 12748 1000 5
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT
12800.0 21504.0  0.0    0.0   215040.0  7864.4   217088.0   16221.8   33024.0 31213.3 4608.0 4252.1      4    0.031   2      0.075    0.106
12800.0 21504.0  0.0    0.0   215040.0  7864.4   217088.0   16221.8   33024.0 31213.3 4608.0 4252.1      4    0.031   2      0.075    0.106
12800.0 21504.0  0.0    0.0   215040.0  7864.4   217088.0   16221.8   33024.0 31213.3 4608.0 4252.1      4    0.031   2      0.075    0.106
12800.0 21504.0  0.0    0.0   215040.0  7864.4   217088.0   16221.8   33024.0 31213.3 4608.0 4252.1      4    0.031   2      0.075    0.106
12800.0 21504.0  0.0    0.0   215040.0  7864.4   217088.0   16221.8   33024.0 31213.3 4608.0 4252.1      4    0.031   2      0.075    0.106
  • S0C:第一个幸存区的大小,单位KB
  • S1C:第二个幸存区的大小
  • S0U:第一个幸存区的使用大小
  • S1U:第二个幸存区的使用大小
  • EC:伊甸园区的大小
  • EU:伊甸园区的使用大小
  • OC:老年代大小
  • OU:老年代使用大小
  • MC:方法区大小(元空间)
  • MU:方法区使用大小
  • CCSC:压缩类空间大小
  • CCSU:压缩类空间使用大小
  • YGC:年轻代垃圾回收次数
  • YGCT:年轻代垃圾回收消耗时间,单位s
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间,单位s
  • GCT:垃圾回收消耗总时间,单位s

堆内存统计

jstat -gccapacity pid

C:\Users\jay>jstat -gccapacity 12748
 NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC       MCMN     MCMX      MC     CCSMN    CCSMX     CCSC    YGC    FGC
174592.0 2790400.0 258048.0 12800.0 21504.0 215040.0   349696.0  5581824.0   217088.0   217088.0      0.0 1077248.0  33024.0      0.0 1048576.0   4608.0      4     2
  • NGCMN:新生代最小容量
  • NGCMX:新生代最大容量
  • NGC:当前新生代容量
  • S0C:第一个幸存区大小
  • S1C:第二个幸存区的大小
  • EC:伊甸园区的大小
  • OGCMN:老年代最小容量
  • OGCMX:老年代最大容量
  • OGC:当前老年代大小
  • OC:当前老年代大小
  • MCMN:最小元数据容量
  • MCMX:最大元数据容量
  • MC:当前元数据空间大小
  • CCSMN:最小压缩类空间大小
  • CCSMX:最大压缩类空间大小
  • CCSC:当前压缩类空间大小
  • YGC:年轻代gc次数
  • FGC:老年代GC次数

新生代垃圾回收统计

jstat -gcnew pid

C:\Users\jay>jstat -gcnew 12748 1000 3
 S0C    S1C    S0U    S1U   TT MTT  DSS      EC       EU     YGC     YGCT
12800.0 21504.0    0.0    0.0  7  15 21504.0 215040.0   7864.4      4    0.031
12800.0 21504.0    0.0    0.0  7  15 21504.0 215040.0   7864.4      4    0.031
12800.0 21504.0    0.0    0.0  7  15 21504.0 215040.0   7864.4      4    0.031

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

新生代内存统计

jstat -gcnewcapacity pid

C:\Users\jay>jstat -gcnewcapacity 12748 1000 3
  NGCMN      NGCMX       NGC      S0CMX     S0C     S1CMX     S1C       ECMX        EC      YGC   FGC
  174592.0  2790400.0   258048.0 929792.0  12800.0 929792.0  21504.0  2789376.0   215040.0     4     2
  174592.0  2790400.0   258048.0 929792.0  12800.0 929792.0  21504.0  2789376.0   215040.0     4     2
  174592.0  2790400.0   258048.0 929792.0  12800.0 929792.0  21504.0  2789376.0   215040.0     4     2

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

老年代垃圾回收统计

jstat -gcold pid

C:\Users\jay>jstat -gcold 12748 1000 3
   MC       MU      CCSC     CCSU       OC          OU       YGC    FGC    FGCT     GCT
 33024.0  31213.3   4608.0   4252.1    217088.0     16221.8      4     2    0.075    0.106
 33024.0  31213.3   4608.0   4252.1    217088.0     16221.8      4     2    0.075    0.106
 33024.0  31213.3   4608.0   4252.1    217088.0     16221.8      4     2    0.075    0.106

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

老年代内存统计

jstat -gcoldcapacity pid

C:\Users\jay>jstat -gcoldcapacity 12748 1000 3
   OGCMN       OGCMX        OGC         OC       YGC   FGC    FGCT     GCT
   349696.0   5581824.0    217088.0    217088.0     4     2    0.075    0.106
   349696.0   5581824.0    217088.0    217088.0     4     2    0.075    0.106
   349696.0   5581824.0    217088.0    217088.0     4     2    0.075    0.106

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

元数据空间内存统计

jstat -gcmetacapacity pid

C:\Users\jay>jstat -gcmetacapacity 12748 1000 3
   MCMN       MCMX        MC       CCSMN      CCSMX       CCSC     YGC   FGC    FGCT     GCT
       0.0  1077248.0    33024.0        0.0  1048576.0     4608.0     4     2    0.075    0.106
       0.0  1077248.0    33024.0        0.0  1048576.0     4608.0     4     2    0.075    0.106
       0.0  1077248.0    33024.0        0.0  1048576.0     4608.0     4     2    0.075    0.106

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

Jstat -gcutil pid

C:\Users\jay>jstat -gcutil 12748 1000 3
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00   3.66   7.47  94.52  92.28      4    0.031     2    0.075    0.106
  0.00   0.00   3.66   7.47  94.52  92.28      4    0.031     2    0.075    0.106
  0.00   0.00   3.66   7.47  94.52  92.28      4    0.031     2    0.075    0.106

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

JVM运行情况评估

用 jstat gc -pid 命令可以计算出如下一些关键数据,有了这些数据就可以采用之前介绍过的优化思路,先给自己的系统设置一些初始性的JVM参数,比如堆内存大小,年轻代大小,Eden和Survivor的比例,老年代的大小,大对象的阈值,大龄对象进入老年代的阈值等。

年轻代对象增长的速率

可以执行命令 jstat -gc pid 1000 10 (每隔1秒执行1次命令,共执行10次),通过观察EU(eden区的使用)来估算每秒eden大概新增多少对象,如果系统负载不高,可以把频率1秒换成1分钟,甚至10分钟来观察整体情况。注意,一般系统可能有高峰期和日常期,所以需要在不同的时间分别估算不同情况下对象增长速率。

Young GC的触发频率和每次耗时

知道年轻代对象增长速率我们就能推根据eden区的大小推算出Young GC大概多久触发一次,Young GC的平均耗时可以通过 YGCT/YGC 公式算出,根据结果我们大概就能知道系统大概多久会因为Young GC的执行而卡顿多久。

每次Young GC后有多少对象存活和进入老年代

这个因为之前已经大概知道Young GC的频率,假设是每5分钟一次,那么可以执行命令 jstat -gc pid 300000 10 ,观察每次结果eden,survivor和老年代使用的变化情况,在每次gc后eden区使用一般会大幅减少,survivor和老年代都有可能增长,这些增长的对象就是每次Young GC后存活的对象,同时还可以看出每次Young GC后进去老年代大概多少对象,从而可以推算出老年代对象增长速率。

Full GC的触发频率和每次耗时

知道了老年代对象的增长速率就可以推算出Full GC的触发频率了,Full GC的每次耗时可以用公式 FGCT/FGC 计算得出。

优化思路

优化思路其实简单来说就是尽量让每次Young GC后的存活对象小于Survivor区域的50%,都留存在年轻代里。尽量别让对象进入老年代。尽量减少Full GC的频率,避免频繁Full GC对JVM性能的影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cuidianjay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值