jvm · 2024-11-17 0

java8 设置 UseParallelGC 和 UseG1GC

一、环境

1.启动容器

为了方便测试,使用 docker 启动一个 ubuntu 系统。设置内存为 4G。

docker run -itd --name ubuntu_1 -m 4G --cap-add CAP_SYS_PTRACE ubuntu:20.04

注意这里设置 CAP_SYS_PTRACE,表示 允许跟踪任何进程,否则使用 jmap 查看堆信息,可能会出现 Operation not permitted 异常

2.安装 jdk

apt install openjdk-8-jdk
apt install openjdk-8-dbg

注意需要安装 openjdk-8-dbg,否则使用 jmap 可能会出现 unknown CollectedHeap type 异常

root@761eaf876cf2:/# java -version
openjdk version "1.8.0_432"

看出安装的 openjdk 版本为 1.8.0_432

二、UseParallelGC

jdk 1.8.0_432 默认的垃圾回收器为 UseParallelGC

1.启动应用

root@761eaf876cf2:/# java -jar app.jar
root@761eaf876cf2:/# jps -l
149 app.jar
root@761eaf876cf2:/# jinfo -flags 149
Attaching to process ID 149, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.432-bga
Non-default VM flags: -XX:CICompilerCount=12 -XX:InitialHeapSize=67108864 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=357564416 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=22020096 -XX:OldSize=45088768 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
Command line: 

通过 jinfo 可以查看,默认参数值为:

  • -XX:InitialHeapSize=67108864 (64MB) (1024*4MB * 1/64,物理内存的 1/64)
  • -XX:MaxHeapSize=1073741824 (1024MB) (1024*4MB * 1/4,物理内存的 1/4)
  • -XX:MaxNewSize=357564416 (341MB)
  • -XX:NewSize=22020096 (21MB)
  • -XX:OldSize=45088768 (43MB)
  • -XX:MinHeapDeltaBytes=524288 (0.5MB)

2.程序刚启动时

jmap 查看堆使用情况

MaxHeapSize (最大堆空间大小) 默认占物理内存的 1/4

root@761eaf876cf2:/# jmap -heap 149
Heap Configuration:
   MinHeapFreeRatio         = 0    # 最小堆使用比例,堆内存剩余空间低于这个比例时会开始变大
   MaxHeapFreeRatio         = 100  # 最大堆可用比例,当堆内存剩余空间高于这个比例时,会开始变小
   MaxHeapSize              = 1073741824 (1024.0MB) # 最大堆空间大小
   NewSize                  = 22020096 (21.0MB)     # 新生代分配大小
   MaxNewSize               = 357564416 (341.0MB)   # 最大可新生代分配大小
   OldSize                  = 45088768 (43.0MB)     # 老年代大小
   NewRatio                 = 2    # 新生代(2个Survivor区和Eden区 )与老年代的堆空间比值,表示新生代:老年代=1:2
   SurvivorRatio            = 8    # 两个Survivor区和Eden区的堆空间比值为 8,表示 S0 : S1 :Eden = 1:1:8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 103809024 (99.0MB)
   used     = 54169080 (51.65966033935547MB)
   free     = 49639944 (47.34033966064453MB)
   52.18147509025805% used
From Space:
   capacity = 6815744 (6.5MB)
   used     = 6798512 (6.4835662841796875MB)
   free     = 17232 (0.0164337158203125MB)
   99.74717360276442% used
To Space:
   capacity = 7864320 (7.5MB)
   used     = 0 (0.0MB)
   free     = 7864320 (7.5MB)
   0.0% used
PS Old Generation
   capacity = 33554432 (32.0MB)
   used     = 7070720 (6.7431640625MB)
   free     = 26483712 (25.2568359375MB)
   21.0723876953125% used

12809 interned Strings occupying 1147360 bytes.
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O      PIDS
761eaf876cf2   ubuntu_1   0.15%     290.7MiB / 4GiB     7.10%     7.26kB / 0B   54MB / 467kB   51

3.执行消耗内存操作时

root@761eaf876cf2:/# jmap -heap 149
Heap Configuration:
   MinHeapFreeRatio         = 0    # 最小堆使用比例,堆内存剩余空间低于这个比例时会开始变大
   MaxHeapFreeRatio         = 100  # 最大堆可用比例,当堆内存剩余空间高于这个比例时,会开始变小
   MaxHeapSize              = 1073741824 (1024.0MB) # 最大堆空间大小
   NewSize                  = 22020096 (21.0MB)     # 新生代分配大小
   MaxNewSize               = 357564416 (341.0MB)   # 最大可新生代分配大小
   OldSize                  = 45088768 (43.0MB)     # 老年代大小
   NewRatio                 = 2    # 新生代(2个Survivor区和Eden区 )与老年代的堆空间比值,表示新生代:老年代=1:2
   SurvivorRatio            = 8    # 两个Survivor区和Eden区的堆空间比值为 8,表示 S0 : S1 :Eden = 1:1:8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 119537664 (114.0MB)
   used     = 87545536 (83.48992919921875MB)
   free     = 31992128 (30.51007080078125MB)
   73.23677999931469% used
From Space:
   capacity = 108003328 (103.0MB)
   used     = 45889968 (43.76408386230469MB)
   free     = 62113360 (59.23591613769531MB)
   42.4894018080628% used
To Space:
   capacity = 119013376 (113.5MB)
   used     = 0 (0.0MB)
   free     = 119013376 (113.5MB)
   0.0% used
PS Old Generation
   capacity = 705691648 (673.0MB)
   used     = 520600464 (496.48329162597656MB)
   free     = 185091184 (176.51670837402344MB)
   73.77166294591034% used

17911 interned Strings occupying 1615960 bytes.

4.java 释放内存后

root@761eaf876cf2:/# jmap -heap 149
Heap Configuration:
   MinHeapFreeRatio         = 0    # 最小堆使用比例,堆内存剩余空间低于这个比例时会开始变大
   MaxHeapFreeRatio         = 100  # 最大堆可用比例,当堆内存剩余空间高于这个比例时,会开始变小
   MaxHeapSize              = 1073741824 (1024.0MB) # 最大堆空间大小
   NewSize                  = 22020096 (21.0MB)     # 新生代分配大小
   MaxNewSize               = 357564416 (341.0MB)   # 最大可新生代分配大小
   OldSize                  = 45088768 (43.0MB)     # 老年代大小
   NewRatio                 = 2    # 新生代(2个Survivor区和Eden区 )与老年代的堆空间比值,表示新生代:老年代=1:2
   SurvivorRatio            = 8    # 两个Survivor区和Eden区的堆空间比值为 8,表示 S0 : S1 :Eden = 1:1:8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 119537664 (114.0MB)
   used     = 905568 (0.863616943359375MB)
   free     = 118632096 (113.13638305664062MB)
   0.7575587222450658% used
From Space:
   capacity = 119013376 (113.5MB)
   used     = 0 (0.0MB)
   free     = 119013376 (113.5MB)
   0.0% used
To Space:
   capacity = 119013376 (113.5MB)
   used     = 0 (0.0MB)
   free     = 119013376 (113.5MB)
   0.0% used
PS Old Generation
   capacity = 705691648 (673.0MB)
   used     = 22917224 (21.855567932128906MB)
   free     = 682774424 (651.1444320678711MB)
   3.247484090955261% used

17914 interned Strings occupying 1616200 bytes.

可以看出 jvm 并没有把内存归还给操作系统

CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT   MEM %     NET I/O           BLOCK I/O     PIDS
761eaf876cf2   ubuntu_1   0.24%     1.163GiB / 4GiB     29.08%    15.9kB / 4.01kB   0B / 1.89MB   51

三、UseG1GC

1.启动应用

root@5f0a685e03b9:/# java -XX:+UseG1GC -jar app.jar
root@5f0a685e03b9:/# jps -l
51 app.jar
root@5f0a685e03b9:/# jinfo -flags 51
Attaching to process ID 51, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.432-bga
Non-default VM flags: -XX:CICompilerCount=12 -XX:ConcGCThreads=3 -XX:G1HeapRegionSize=1048576 -XX:InitialHeapSize=67108864 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=643825664 -XX:MinHeapDeltaBytes=1048576 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC 
Command line:  -XX:+UseG1GC

通过 jinfo 可以查看,参数值为:

  • -XX:InitialHeapSize=67108864 (64MB) (1024*4MB * 1/64,物理内存的 1/64)
  • -XX:MaxHeapSize=1073741824 (1024MB) (1024*4MB * 1/4,物理内存的 1/4)
  • -XX:MaxNewSize=643825664 (614MB)
  • -XX:G1HeapRegionSize=1048576 (1MB)
  • -XX:MarkStackSize=4194304 (4MB)
  • -XX:MinHeapDeltaBytes=1048576 (1MB)

2.程序刚启动时

jmap 查看堆使用情况

MaxHeapSize (最大堆空间大小) 默认占物理内存的 1/4

root@5f0a685e03b9:/# jmap -heap 51
Attaching to process ID 51, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.432-bga

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

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 1073741824 (1024.0MB)           # 最大堆空间大小
   NewSize                  = 1363144 (1.2999954223632812MB)  # 新生代分配大小
   MaxNewSize               = 643825664 (614.0MB)             # 最大可新生代分配大小
   OldSize                  = 5452592 (5.1999969482421875MB)  # 老年代大小
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 1048576 (1.0MB)

Heap Usage:
G1 Heap:
   regions  = 1024
   capacity = 1073741824 (1024.0MB)
   used     = 37017088 (35.30224609375MB)
   free     = 1036724736 (988.69775390625MB)
   3.4474849700927734% used
G1 Young Generation:
Eden Space:
   regions  = 14
   capacity = 33554432 (32.0MB)
   used     = 14680064 (14.0MB)
   free     = 18874368 (18.0MB)
   43.75% used
Survivor Space:
   regions  = 5
   capacity = 5242880 (5.0MB)
   used     = 5242880 (5.0MB)
   free     = 0 (0.0MB)
   100.0% used
G1 Old Generation:
   regions  = 17
   capacity = 28311552 (27.0MB)
   used     = 17094144 (16.30224609375MB)
   free     = 11217408 (10.69775390625MB)
   60.378689236111114% used

12821 interned Strings occupying 1147736 bytes.
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT   MEM %     NET I/O       BLOCK I/O       PIDS
5f0a685e03b9   ubuntu_1   0.14%     234.6MiB / 4GiB     5.73%     3.42kB / 0B   176kB / 324kB   70

3.执行消耗内存操作时

root@5f0a685e03b9:/# jmap -heap 51
Attaching to process ID 51, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.432-bga

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

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 1073741824 (1024.0MB)           # 最大堆空间大小
   NewSize                  = 1363144 (1.2999954223632812MB)  # 新生代分配大小
   MaxNewSize               = 643825664 (614.0MB)             # 最大可新生代分配大小
   OldSize                  = 5452592 (5.1999969482421875MB)  # 老年代大小
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 1048576 (1.0MB)

Heap Usage:
G1 Heap:
   regions  = 1024
   capacity = 1073741824 (1024.0MB)
   used     = 1072915576 (1023.212028503418MB)
   free     = 826248 (0.7879714965820312MB)
   99.92304965853691% used
G1 Young Generation:
Eden Space:
   regions  = 0
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   0.0% used
Survivor Space:
   regions  = 0
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   0.0% used
G1 Old Generation:
   regions  = 0
   capacity = 1073741824 (1024.0MB)
   used     = 1072915576 (1023.212028503418MB)
   free     = 826248 (0.7879714965820312MB)
   99.92304965853691% used

10904 interned Strings occupying 1000736 bytes.
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT   MEM %     NET I/O           BLOCK I/O        PIDS
5f0a685e03b9   ubuntu_2   157.00%   1.233GiB / 4GiB     30.83%    5.09kB / 1.05kB   176kB / 1.22MB   69

4.java 释放内存后

root@5f0a685e03b9:/# jmap -heap 51
Attaching to process ID 125, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.432-bga

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

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 1073741824 (1024.0MB)           # 最大堆空间大小
   NewSize                  = 1363144 (1.2999954223632812MB)  # 新生代分配大小
   MaxNewSize               = 643825664 (614.0MB)             # 最大可新生代分配大小
   OldSize                  = 5452592 (5.1999969482421875MB)  # 老年代大小
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 1048576 (1.0MB)

Heap Usage:
G1 Heap:
   regions  = 1024
   capacity = 1073741824 (1024.0MB)
   used     = 10084584 (9.617408752441406MB)
   free     = 1063657240 (1014.3825912475586MB)
   0.9392000734806061% used
G1 Young Generation:
Eden Space:
   regions  = 0
   capacity = 10485760 (10.0MB)
   used     = 0 (0.0MB)
   free     = 10485760 (10.0MB)
   0.0% used
Survivor Space:
   regions  = 0
   capacity = 0 (0.0MB)
   used     = 0 (0.0MB)
   free     = 0 (0.0MB)
   0.0% used
G1 Old Generation:
   regions  = 10
   capacity = 24117248 (23.0MB)
   used     = 10084584 (9.617408752441406MB)
   free     = 14032664 (13.382591247558594MB)
   41.814820662788726% used

13226 interned Strings occupying 1180144 bytes.

可以看出 jvm 并把内存归还给操作系统

CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT   MEM %     NET I/O           BLOCK I/O        PIDS
5f0a685e03b9   ubuntu_1   0.28%     220.6MiB / 4GiB     5.39%     5.42kB / 1.75kB   49.2kB / 401kB   70