Full GC 和 Minor GC

news/2025/2/7 8:06:17/

目录

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是对老年代的垃圾回收

参考资料 & 鸣谢

  • Major GC和Full GC的区别是什么?触发条件呢?- 知乎-RednaxelaFX的回答
  • 极客时间专栏 《深入拆解Java虚拟机》
  • 从实际案例聊聊Java应用的GC优化-美团技术团队
  • 译文-Minor GC vs Major GC vs Full GC

http://www.ppmy.cn/news/882184.html

相关文章

JVM:28 面试题:解释一下什么是Young GC和Full GC?

(1)Minor GC / Young GC “新生代” 也可以称之为 “年轻代” ,这两个名词是等价的。在年轻代中的Eden内存区域被占满之后实际上就需要出发年轻代的GC,或者是新生代的GC。 此时这个新生代GC,就是所谓的 “Minor GC”…

频繁gc是什么意思_linux查看是否频繁gc

1.监控GC的状态 使用各种JVM工具,查看当前日志,分析当前JVM参数设置,并且分析当前堆内存快照和gc日志,根据实际的各区域内存划分和GC执行时间,觉得是否进行优化。 举一个例子: 系统崩溃前的一些现象: 每次垃圾回收的时间越来越长,由之前的10ms延长到50ms左右,FullGC的…

Minor GC、Young GC、Old GC、Major GC、Mixed GC、Full GC都是什么?

文章目录 各个GC的概念1、Minor GC和Young GC2、Old GC和Major GC3、Mixed GC4、Full GC 两个大类partial GC和Full GC:各个GC的触发条件触发young GC触发Full GC触发Major GC/Old GC触发Mixed GC 各个GC的概念 1、Minor GC和Young GC Minor GC 和 Young GC&#…

什么是GC Root

1 GC ROOT的定义 我们知道,JVM中判断一个对象是否标记为可回收的对象是根据可达性分析算法,顾名思义,可达性分析需要知道当前对象(是否需要回收的对象)的起点,而这个起点对象在当前时刻一定是存活的&#…

JAVA GC是什么?为什么要有GC?

GC是垃圾收集的意思。 内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃。 Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法…

什么是java full gc_关于Java垃圾回收,你必须要知道FullGC是什么

本文共3198字,是本人前几天面试被提问到的一个问题,将在该文中阐述关于Java垃圾回收——Full GC的相关知识,包括定义、触发条件、具体过程。 前几天面试的时候,面试官在最后问了我一个有关Full GC的垃圾回收问题,希望我说明下该GC的定义、以及是如何触发的问题,有感便记下…

杂谈之什么是FullGC

本文基于JDK 1.8,使用的收集器为ParNew CMS 前言 这篇文章的起因是这样的,在上周五凌晨很苦逼得参加双十一压测值班的时候,有个业务方突然打电话来说我们提供的客户端存在内存泄漏问题导致线上应用持续full gc,本来已经快要睡着的我立马就精…

java中gc是什么_java什么是gc

GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃。 Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释…