G1内存模型
G1虽然抛弃了将新生代和老年代作为整块内存空间的方式,但依然保留了新生代和老年代的概念。只是老年代和新生代的内存空间不再是物理连续的了,它们都是Region的集合。
G1将所有Region分为四种类型:Eden、Survivor、Old、Humongous。
默认新生代的Region内存占堆空间的5%,如果堆空间大小为4096MB,那么新生代占用200MB左右的内存,按照每个Region为2MB,对应就是100个Region。也可以通过参数-XX:G1NewSizePercent设置新生代初始占比。
在系统运行过程中,JVM会动态地给年轻代增加更多的Region,但新生代的占比最多不会超过60%,可以通过参数-XX:G1MaxNewSizePercent设置。Region的区域类型是动态变化的,可能之前是年轻代,经过了垃圾回收之后就变成了老年代。
G1中的新生代依然与经典垃圾收集器中一样,分为Eden区和Survivor区,默认比例也是8:1:1,如果新生代有100个Region,那么就是Eden区占用80个,两个Survivor区各占用10个。
G1收集器对于对象从新生代转移到老年代与CMS等经典垃圾收集器是一样的,但对于大对象的处理有所不同。G1为大对象的内存分配专门设计了一个Humongous类型的Region,而不再是让对象直接进入老年代的Region。
在G1中,大对象的判断是超过一个Region大小的50%,按照每个Region大小为2MB来计算,只要对象超过了1MB,就会被放入到Humongous的Region中,如果一个对象太大,一个Region放不下,那么G1会寻找连续的H分区来存储,如果寻找不到连续的H区的话,就不得不启动 Full GC 了。
在进行Full GC的时候除了要收集新生代和老年代的Region外,还会将Humongous的Region一并进行回收。
G1的的垃圾收集过程
G1的垃圾收集分为YoungGC、Mixed GC和Full GC。
YoungGC
当Eden区已满,JVM分配对象到Eden区失败时,便会触发一次STW式的年轻代收集young GC,将 Eden 区存活的对象将被拷贝到 to survivor 区;from survivor 区存活的对象则根据存活次数阈值分别晋升到 to survivor 区和老年代中;如果 survivor 空间不够,Eden区的部分数据会直接晋升到年老代空间