22_模拟 JVM 的 Full GC 场景
约 829 字大约 3 分钟
2024-08-10
JVM 参数配置
下面这些参数基于 JDK1.8 版本来配置的,忘记怎么设置的可以回看 07_动手实验:系统部署时如何设置JVM内存大小 的内容
这里主要将大对象阈值参数 -XX:PretenureSizeThreshold 设置为 3MB
//初始新生代大小 最大新生代大小 初始堆内存大小 最大堆内存大小 Eden区占比新生代比例 大对象阈值 新生代垃圾器 ParNew 老年代垃圾器 CMS 打印详细 GC 日志 打印每次发生GC的时间 将GC 日志写入磁盘文件
-XX:NewSize=10M -XX:MaxNewSize=10M -XX:InitialHeapSize=20M -XX:MaxHeapSize=20M -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3M -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log模拟 Full GC 场景
public static void main(String[] args) {
byte[] array1 = new byte[4 * 1024 * 1024];
System.gc();
// 这里需要改变 array1 引用地址,否则 Old GC 时会 OutOfMemoryError
array1 = null;
byte[] array2 = new byte[2 * 1024 * 1024];
byte[] array3 = new byte[2 * 1024 * 1024];
byte[] array4 = new byte[2 * 1024 * 1024];
byte[] array5 = new byte[2 * 1024 * 1024];
}上面为模拟 Full GC 场景的代码,我们进行简要说明
1、
array1引用的数组对象大小为4MB,超过我们设置的大对象阈值3MB,所以会直接进入老年代2、
Eden区大小为8MB,array2、array3、array4引用的数组大小均为2MB,总共6MB在Eden区是可以分配下的3、
array引用数组对象分配内存时候,Eden区是放不下的,array2、array3、array4也均还有引用,老年代大小为10MB,已经有4MB的数组对象了,array2、array3、array4的数组对象放不下,此时就需要进行一次Full GC,如下图所示

我们再来看看下面 GC 日志,我们不逐行分析,说几个点是否满足我们的预期
1、
eden space 8192K, 29% used:Eden区最后放一个2MB数组,占比约25%2、
concurrent mark-sweep generation total 10240K, used 7045K:老年代放入了array2、array3、array4引用的共6MB数组约6144K
Java HotSpot(TM) 64-Bit Server VM (25.92-b14) for windows-amd64 JRE (1.8.0_92-b14), built on Mar 31 2016 21:03:04 by "java_re" with MS VC++ 10.0 (VS2010)
Memory: 4k page, physical 25038040k(4725680k free), swap 47862644k(14033700k free)
CommandLine flags: -XX:InitialHeapSize=20971520 -XX:MaxHeapSize=20971520 -XX:MaxNewSize=10485760 -XX:NewSize=10485760 -XX:OldPLABSize=16 -XX:PretenureSizeThreshold=3145728 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC
0.182: [Full GC (System.gc()) 0.182: [CMS: 4096K->5188K(10240K), 0.0047019 secs] 7316K->5188K(19456K), [Metaspace: 3210K->3210K(1056768K)], 0.0048229 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
0.189: [GC (Allocation Failure) 0.189: [ParNew (promotion failed): 6471K->6519K(9216K), 0.0021009 secs]0.191: [CMS: 9286K->7045K(10240K), 0.0039821 secs] 11659K->7045K(19456K), [Metaspace: 3315K->3315K(1056768K)], 0.0061597 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
0.207: [GC (CMS Initial Mark) [1 CMS-initial-mark: 7045K(10240K)] 9177K(19456K), 0.0001359 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
0.207: [CMS-concurrent-mark-start]
0.208: [CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
0.208: [CMS-concurrent-preclean-start]
0.208: [CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
0.208: [CMS-concurrent-abortable-preclean-start]
Heap
par new generation total 9216K, used 2378K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
eden space 8192K, 29% used [0x00000000fec00000, 0x00000000fee52870, 0x00000000ff400000)
from space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000)
to space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000)
concurrent mark-sweep generation total 10240K, used 7045K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
Metaspace used 3345K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 365K, capacity 388K, committed 512K, reserved 1048576K