Full GC 和 Minor GC

目录

Full GC

Full GC的触发条件

Minor GC

触发条件

Minor GC的过程

Survivor区对象晋升位老年代对象的条件

Minor GC的问题与卡表分析

关于 Major GC的说明

小结

参考资料 & 鸣谢


Full GC

Full GC 就是收集整个堆,包括新生代,老年代等收集所有部分的模式

针对 HotSpot VM 的实现,它里面的GC其实准确分类有两种:

  • Partial GC(局部 GC): 并不收集整个 GC 堆的模式
    • Young GC: 只收集 young gen 的 GC,Young GC 还有种说法就叫做 "Minor GC"
    • Old GC: 只收集 old gen 的 GC。只有垃圾收集器 CMS 的 concurrent collection 是这个模式
    • Mixed GC: 收集整个 young gen 以及部分 old gen 的 GC。只有垃圾收集器 G1 有这个模式
  • Full GC: 收集整个堆,包括 新生代,老年代,永久代(在 JDK 1.8及以后,永久代被移除,换为metaspace 元空间)等所有部分的模式

Full GC 的触发条件

针对不同的垃圾收集器,Full GC的触发条件可能不都一样。按HotSpot VM的serial GC的实现来看,触发条件是:

1)调用System.gc时,系统建议执行Full GC,但是不必然执行。

(2)老年代空间不足

(3)方法区空间不足

(4)通过 Minor GC 后进入老年代的平均大小大于老年代的可用内存

(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小

HotSpot VM 里其他非并发 GC 的触发条件复杂一些,不过大致原理与上面说的其实一样。

在 Parallel Scavenge 收集器下,默认是在要触发 full GC前先执行一次 young GC,并且两次 GC 之间能让应用程序稍微运行一小下,以期降低 full GC 的暂停时间 (因为 young GC 会尽量清理了 young gen 的死对象,减少了 full GC 的工作量)。控制这个行为的VM参数是: -XX:+ScavengeBeforeFullGC

并发GC的触发条件就不一样,以 CMS GC为例,它主要是定时去检查old gen的使用量,但使用量超过了触发比例就会启动一次 CMS GC,对old gen做并发收集

Minor GC

Minor GC 是俗称,新生代(新生代分为一个 Eden区和两个Survivor区)的垃圾收集叫做 Minor GC:

触发条件

当 Eden 区的空间耗尽了怎么办?这个时候 Java虚拟机便会触发一次 Minor GC来收集新生代的垃圾,存活下来的对象,则会被送到 Survivor区。

简单说就是当新生代的Eden区满的时候触发 Minor GC

Minor GC的过程

前面提到,新生代共有 两个 Survivor区,我们分别用 from 和 to来指代。其中 to 指向的Survivor区是空的。

当发生 Minor GC时,Eden 区和 from 指向的 Survivor 区中的存活对象会被复制(此处采用标记 - 复制算法)到 to 指向的 Survivor区中,然后交换 from 和 to指针,以保证下一次 Minor GC时,to 指向的 Survivor区还是空的

注意:  from 与 to 只是两个指针,它们变动的,to 指针指向的 Survivor 区是空的。

Survivor区对象晋升位老年代对象的条件

Java虚拟机会记录 Survivor区中的对象一共被来回复制了几次。如果一个对象被复制的次数为 15 (对应虚拟机参数 -XX:+MaxTenuringThreshold),那么该对象将被晋升为至老年代,(至于为什么是 15次,原因是 HotSpot会在对象头的中的标记字段里记录年龄,分配到的空间只有4位,所以最多只能记录到15)。另外,如果单个 Survivor 区已经被占用了 50% (对应虚拟机参数: -XX:TargetSurvivorRatio),那么较高复制次数的对象也会被晋升至老年代。

当 Survivor 区的部分对象晋升到老年代后,老年代的占用量通常会升高。

注意

在Minor GC过程中,Survivor 可能不足以容纳Eden和另一个Survivor中的存活对象。如果Survivor中的存活对象溢出,多余的对象将被移到老年代,这称为过早提升(Premature Promotion),这会导致老年代中短期存活对象的增长,可能会引发严重的性能问题。再进一步说,在Minor GC过程中,如果老年代满了而无法容纳更多的对象,Minor GC 之后通常就会进行Full GC,这将导致遍历整个Java堆,这称为提升失败(Promotion Failure)。至于解决办法,这就涉及到对应用程序的调优问题了,这里就不叙述了,如有兴趣,请自行查阅相关资料

Minor GC的问题与卡表分析

Minor GC存在一个问题就是,老年代的对象可能引用新生代的对象,在标记存活对象的时候,就需要扫描老年代的对象,如果该对象拥有对新生代对象的引用,那么这个引用也会被作为 GC Roots。这相当于就做了全堆扫描

JVM如何避免Minor GC扫描全堆

HotSpot 给出的解决方案是 一项叫做 卡表 的技术。如下图所示:

card table

卡表的具体策略是将老年代的空间分成大小为 512B的若干张卡,并且维护一个卡表,卡表本省是字节数组,数组中的每个元素对应着一张卡,其实就是一个标识位,这个标识位代表对应的卡是否可能存有指向新生代对象的引用,如果可能存在,那么我们认为这张卡是脏的,即脏卡。如上图所示,卡表3被标记为脏。

在进行Minor GC的时候,我们便可以不用扫描整个老年代,而是在卡表中寻找脏卡,并将脏卡中的老年代指向新生代的引用加入到 Minor GC的GC Roots里,当完成所有脏卡的扫描之后,Java 虚拟机便会将所有脏卡的标识位清零。这样虚拟机以空间换时间,避免了全表扫描

关于 Major GC的说明

除了Full GC和Minor GC外,还有一种说法叫做 "Major GC":

Major GC通常是跟full GC是等价的,收集整个GC堆,但因为 HotSpot VM发展这么多年,外界对各种名词的解读已经完全混乱了,当有人说"Major GC"的时候一定要问清楚他想要指的是上面的 full GC还是 old GC

以上是 R大关于 Major GC的说法,比较权威的。在网上还流行着另外一种说法就是 Major GC是对老年代的垃圾回收

参考资料 & 鸣谢

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: minor gc 和 full gc 是 Java 虚拟机中的两种垃圾回收方式。 minor gc 是指对年轻代进行垃圾回收,年轻代中的对象一般存活时间较短,因此垃圾回收频率较高。minor gc 通常会暂停应用程序的执行,直到垃圾回收完成。 full gc 是指对整个堆进行垃圾回收,包括年轻代和老年代。老年代中的对象一般存活时间较长,因此垃圾回收频率较低。full gc 会暂停应用程序的执行,直到垃圾回收完成,因此会对应用程序的性能产生较大影响。 因此,minor gc 和 full gc 的区别在于垃圾回收的范围和频率,以及对应用程序性能的影响程度。 ### 回答2: Minor GC(Young GC)和Full GC(Major GC)是Java虚拟机(JVM)中垃圾收集的两个重要阶段。 Minor GC主要负责清理年轻代(Young Generation)的垃圾对象,年轻代又分为Eden区、Survivor 0区和Survivor 1区。当Eden区满时,触发Minor GC。在这个过程中,存活的对象会被复制到Survivor区,然后进行垃圾回收。Minor GC是一个短暂的过程,通常不会引起长时间的应用暂停。因为大部分对象在年轻代很快就被回收,所以Minor GC的频率比较高。 Full GC则是对整个堆内存进行垃圾回收。它主要清理老年代(Old Generation)和永久代(Perm Generation)中的垃圾对象。Old Generation存放生命周期较长的对象,而Perm Generation存放类信息、常量等。Full GC的频率较低,一般在触发条件满足时才会发生。Full GC执行时间较长,会导致应用的停顿,并且会造成较大开销。 总结而言,Minor GC主要针对年轻代的回收,频率较高但耗时较短,而Full GC则是对整个堆内存进行垃圾回收,频率较低但耗时较长。Minor GC的目标是快速地回收生命周期短的对象,而Full GC则是为了清理老年代和永久代中的垃圾对象以防止内存不足。了解Minor GC和Full GC的区别有助于我们优化JVM的垃圾回收策略,提高应用的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值