minor GC、Major GC、Full GC区别

hotspot vm的gc分为部分收集和整堆收集。

部分收集

  • 新生代收集:minorGC又称YoungGC,只是对Eden和S0,S1回收,只有Eden满的时候才会引发GC,GC就会引发STW(stop the world),虽然GC很频繁,但是回收速度很快,因此总的来说不会太影响用户线程。
  • 老年代收集:Major GC/Old GC,只有CMS GC会有单独收集老年代的行为,这里需要注意的是很容易和full GC混淆,主要区分就是是不是专门回收老年代
  • 混合收集:Mixed GC,收集整个新生代以及部分老年代的垃圾收集。

整堆收集

Full GC,收集整个java堆和方法区的垃圾。
触发条件:

  1. 系统代码调用: system.gc()

  2. 老年代空间不足,有三个纬度:
    ①老年代本身内存不足了
    ②经过正常minor gc 后进入老年代时,老年代内存不足
    ③由eden区,幸存者区的from到to时,出现内存不足,此时需要直接到老年代,但此时老年代空间也不足

  3. 方法区空间不足
    full gc是开发中要避免的,因为耗费的时间会长很多。

在出现oom之前一定会经过一次full gc

下面写了一个程序进行示例:

package com.lydon.test;
import java.util.ArrayList;
public class GCTest {
    
    
    public static void main(String[] args) {
    
    
        int i=0;
        try {
    
    
            ArrayList<String> list = new ArrayList<>();
            String testStr="hello world";
            while (true){
    
    
                list.add(testStr);
                testStr+=testStr;
                i++;
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
            System.out.println("遍历次数为:"+i);
        }
    }
}

可以通过加上jvm参数
-Xms9m -Xmx9m -XX:NewRatio=2 -XX:SurvivorRatio=8 -XX:+PrintGCDetails
来通过gc日志来分析gc过程:

[GC (Allocation Failure) [PSYoungGen: 2026K->488K(2560K)] 2026K->720K(9728K), 0.0023395 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 2198K->510K(2560K)] 2430K->1401K(9728K), 0.0018080 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 2323K->430K(2560K)] 3214K->2201K(9728K), 0.0013937 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 1216K->446K(2560K)] 7211K->6441K(9728K), 0.0013011 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 446K->430K(2560K)] 6441K->6425K(9728K), 0.0008020 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 430K->0K(2560K)] [ParOldGen: 5995K->4931K(7168K)] 6425K->4931K(9728K), [Metaspace: 3489K->3489K(1056768K)], 0.0056285 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] 4931K->4931K(9728K), 0.0008219 secs] [Times: user=0.02 sys=0.01, real=0.02 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 4931K->4863K(7168K)] 4931K->4863K(9728K), [Metaspace: 3489K->3489K(1056768K)], 0.0125710 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 2560K, used 100K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
  eden space 2048K, 4% used [0x00000000ffd00000,0x00000000ffd192a8,0x00000000fff00000)
  from space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
  to   space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
 ParOldGen       total 7168K, used 4863K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
  object space 7168K, 67% used [0x00000000ff600000,0x00000000ffabfec0,0x00000000ffd00000)
 Metaspace       used 3522K, capacity 4502K, committed 4864K, reserved 1056768K
  class space    used 391K, capacity 394K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3332)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
	at java.lang.StringBuilder.append(StringBuilder.java:136)
	at com.lydon.test.GCTest.main(GCTest.java:11)

Process finished with exit code 1

猜你喜欢

转载自blog.csdn.net/lyd135364/article/details/121064858