JVM G1

本文介绍了JVM垃圾收集器的发展历程,从Serial收集器到G1收集器,并重点解析了G1收集器的特点与应用场景。G1通过分区管理堆内存,解决了内存碎片等问题,并能有效控制垃圾收集时的停顿时间。

JVM垃圾收集器发展历程

  • 第一阶段,Serial(串行)收集器

    在jdk1.3.1之前,java虚拟机仅仅能使用Serial收集器。 Serial收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅是说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。

  • 第二阶段,Parallel(并行)收集器

    Parallel收集器也称吞吐量收集器,相比Serial收集器,Parallel最主要的优势在于使用多线程去完成垃圾清理工作,这样可以充分利用多核的特性,大幅降低gc时间。

  • 第三阶段,CMS(并发)收集器

    CMS收集器在Minor GC时会暂停所有的应用线程,并以多线程的方式进行垃圾回收。在Full GC时不再暂停应用线程,而是使用若干个后台线程定期的对老年代空间进行扫描,及时回收其中不再使用的对象。

  • 第四阶段,G1(并发)收集器

    G1收集器(或者垃圾优先收集器)的设计初衷是为了尽量缩短处理超大堆(大于4GB)时产生的停顿。相对于CMS的优势而言是内存碎片的产生率大大降低。

JVM垃圾收集器种类

  • 1.新生代

    Serial (第一代)
    PraNew (第二代)
    Parallel Scavenge (第三代)
    G1收集器(第四代)

  • 2.老年代

    Serial Old (第一代)
    Parallel Old (第二代)
    CMS (第三代)
    G1收集器 (第四代)

G1收集器概述

  • 1.G1收集器的最大特点:
    G1收集器最大的特点是引入了分区的思路,弱化了分代的概念。
    合理利用垃圾收集各个周期的资源,解决了其他收集器甚至CMS的众多缺陷。

  • 2.G1相比较CMS的改进
    算法:G1基于标记-整理算法,不会产生空间碎片,分配大对象时不会无法得到连续的空间而提前触发一次FULL GC。
    停顿时间可控:G1可以通过设置预期停顿时间(Pause Time)来控制垃圾收集时间避免应应用雪崩现象。
    并行与并发:G1能更充分的利用CPU,多核环境下的硬件优势来缩短stop the world的停顿时间。

  • 3.CMS和G1的区别
    CMS中,堆被分为PermGen,YoungGen,OldGen;而YoungGen又分了两个survivo区域。在G1中,堆被平均分成几个区域(region),在每个区域中,虽然也保留了新老代的概念,但是收集器是以整个区域为单位收集的。
    G1在回收内存后会马上同时做合并空闲内存的工作、而CMS默认是在STW(stop the world)的时候做。
    G1会在Young GC中使用、而CMS只能在O区使用。

G1收集器的应用场景

1.8之前,JVM分为新生代、老年代、持久代。1.8之后,元空间取代了持久代。

  • G1收集器的内存模型
    在这里插入图片描述

  • G1堆内存结构
    堆内存会被切分成为很多固定大小的区域(region),每个是连续范围的虚拟内存。
    堆内存中一个区域(region)的大小可以通过-XX:G1HeapRegionSize参数指定,大小区间最小1M,最大32M,总之是2的幂次方。
    默认把堆内存分为2048份。

  • G1堆内存分配
    每个Region被标记了E,S,O,H,这些区域在逻辑上被映射为Eden,Survivor和老年代。
    存活的对象从一个区域转移(即复制或移动)到另一个区域。区域被设计为并行收集垃圾,可能会暂停所有应用线程。
    如上图所示,区域可以分配到Eden,survivor和老年代。此外,还有第四种类型,被称为巨型区域(Humongous Region)。Humongous区域是为了那些存储超过50%标准region大小的对象而设计的,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启用Full GC。

G1回收流程

  • G1收集器的阶段分以下几个步骤
    在这里插入图片描述
    1)G1执行的第一阶段:初始标记(Initial Marking)
    这个阶段是STW(stop the world)的,所有应用线程会被暂停,标记出从GC Root开始直接可达的对象。
    2)G1执行的第二个阶段:并发标记
    从GC Roots开始对堆中对象进行可达性分析,找出存活对象,耗时较长。当并发标记完成后,开始最终标记(Final Marking)阶段
    3)最终标记(标记那些在并发标记阶段发生变化的对象,将被回收)
    4)筛选回收(首先对各个Region的回收价值和成本进行排序,根据用户所期待的GC停顿时间指定回收计划,回收一部分Region)
    最后,G1中提供了两种模式垃圾回收模式,Young GC和Mixed GC,两种都是Stop The World(STW)的。

G1的GC模式

  • Young GC年轻代收集
    在分配一般对象(非巨型对象)时,当所有eden region 使用达到最大阈值并且无法申请足够内存时,会触发一次YoungGC。每次younggc会回收所有Eden以及Survivor区,并且将存活对象复制到Old区以及另一部分的Survivor区。

    Young GC的回收过程如下:
    跟扫描,跟CMS类似,Stop the world,扫描GC Roots对象。
    处理Dirty card,更新RSet.
    扫描RSet,扫描RSet中所有old区对扫描到的young区或者survivor去的引用。
    拷贝扫描出的存活的对象到survivor2/old区
    处理引用队列,软引用,弱引用,虚引用

    Mixed GC
    当越来越多的对象晋升到老年代old region时,为了避免内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即mixed gc,该算法并不适宜个old gc,除了回收整个young region,还会回收一部分的old region,这里需要注意:是一部分老年代,而不是全部老年代,可以选择那些old region进行收集,从而可以对了垃圾回收的耗时时间进行控制。
    G1没有full GC的概念,需要full GC时,调用serialOldGC进行全堆扫描(包括eden、survivor、o、perm)。

G1的推荐应用

  • G1的第一个重要特点是为用户的应用程序的提供一个低GC延时和大内存GC的解决方案。这意味着堆大小6GB或者更大,稳定和可预测的暂停时间将低于0.5秒。
  • 如果应用程序使用CMS或ParallelOld垃圾回收器具有一个或多个一下特征,将有利于切换到G1:
    Full GC持续时间太长或太频繁
    对象分配率或年轻代升级老年代很频繁
    不期望的很长的垃圾收集时间或压缩暂停(超过0.5至1秒)

注意:如果你正在使用CMS或ParallelOld收集器,并且你的应用程序没有遇到长时间的垃圾收集暂停,则保持与您的当前收集器是很好的,升级JDK并不必要更新收集器为G1。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值