JVM-GC日志

先提出问题?为什么有时候发现 内存用了很多了,但是没有被回收。手动触发GC后,才回收了很多内存。

JVM设置如下参数:

1. 堆设置2g

2. 新生代设置1g,那么老年代自然也是1g

3. 设置打印GC信息,并输出到 gc.log 文件

-Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/gc.log

堆信息如下:

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 2147483648 (2048.0MB)
   NewSize                  = 1073741824 (1024.0MB)
   MaxNewSize               = 1073741824 (1024.0MB)
   OldSize                  = 1073741824 (1024.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB) 

应用启动后gc日志:

CommandLine flags: -XX:InitialHeapSize=2147483648 -XX:MaxHeapSize=2147483648 -XX:MaxNewSize=1073741824 -XX:NewSize=1073741824 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC 
2023-06-21T14:27:22.324+0800: 1.914: [GC (Metadata GC Threshold) [PSYoungGen: 534779K->13945K(917504K)] 534779K->14033K(1966080K), 0.0344142 secs] [Times: user=0.08 sys=0.00, real=0.04 secs] 
2023-06-21T14:27:22.359+0800: 1.948: [Full GC (Metadata GC Threshold) [PSYoungGen: 13945K->0K(917504K)] [ParOldGen: 88K->13799K(1048576K)] 14033K->13799K(1966080K), [Metaspace: 20532K->20532K(1067008K)], 0.0357165 secs] [Times: user=0.21 sys=0.02, real=0.03 secs] 
2023-06-21T14:27:24.014+0800: 3.603: [GC (Metadata GC Threshold) [PSYoungGen: 690461K->27760K(917504K)] 704261K->41567K(1966080K), 0.0691493 secs] [Times: user=0.21 sys=0.01, real=0.07 secs] 
2023-06-21T14:27:24.083+0800: 3.673: [Full GC (Metadata GC Threshold) [PSYoungGen: 27760K->0K(917504K)] [ParOldGen: 13807K->33241K(1048576K)] 41567K->33241K(1966080K), [Metaspace: 34133K->34133K(1079296K)], 0.0660470 secs] [Times: user=0.46 sys=0.01, real=0.07 secs] 
2023-06-21T14:27:27.152+0800: 6.741: [GC (Allocation Failure) [PSYoungGen: 786432K->27067K(917504K)] 819673K->60317K(1966080K), 0.0530390 secs] [Times: user=0.11 sys=0.01, real=0.05 secs] 
2023-06-21T14:27:33.056+0800: 12.645: [GC (Metadata GC Threshold) [PSYoungGen: 114700K->12304K(917504K)] 147949K->45561K(1966080K), 0.0118059 secs] [Times: user=0.04 sys=0.00, real=0.02 secs] 
2023-06-21T14:27:33.068+0800: 12.658: [Full GC (Metadata GC Threshold) [PSYoungGen: 12304K->0K(917504K)] [ParOldGen: 33257K->21336K(1048576K)] 45561K->21336K(1966080K), [Metaspace: 56024K->56024K(1101824K)], 0.1189569 secs] [Times: user=0.54 sys=0.02, real=0.12 secs] 
2023-06-21T14:28:10.725+0800: 50.314: [GC (Allocation Failure) [PSYoungGen: 786432K->5783K(917504K)] 807768K->27128K(1966080K), 0.0070404 secs] [Times: user=0.01 sys=0.01, real=0.01 secs] 

 一般gc日志格式如下:

GC|Full GC (原因) [年轻代:回收前->回收后(空间总大小)]  [老年代:回收前->回收后(空间总大小)]  回收前 -> 回收后(堆空间大小) [其他空间]耗时 

每个空间用 [] 扩起来,不同空间用 ,分割

第一行:因为 Metadata GC Threshold 引发的GC,年轻代 空间进行了GC

第二行:因为 Metadata GC Threshold 引发的 Full GC,年轻代、老年代、元空间 都进行GC

发现总共进行了3次Full GC,元空间 再变大。

由于JVM 元空间默认值21M,所以 配置 -XX:MetaspaceSize=128m,再此启动应用:

2023-06-21T15:18:18.336+0800: 2.364: [GC (Allocation Failure) [PSYoungGen: 786432K->19872K(917504K)] 786432K->19960K(1966080K), 0.0583594 secs] [Times: user=0.14 sys=0.01, real=0.06 secs] 
2023-06-21T15:18:21.316+0800: 5.344: [GC (Allocation Failure) [PSYoungGen: 806304K->43337K(917504K)] 806392K->43457K(1966080K), 0.1278580 secs] [Times: user=0.70 sys=0.04, real=0.13 secs] 

没有Full GC了,原来是因为 元空间太小,触发了 Full GC。

通过GC日志,可以看出来,每次GC 后面括号里都有原因,像 Allocation Failure。这就是 GC的触发原因,当分配空间失败,也就是 当前内存不足了,就会触发GC。那么 当 内存空间足够分配新对象,即使之前的 对象已经die了,也不随便GC。

你可能感兴趣的:(笔记,JVM,jvm)