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