G1 垃圾收集器

一,垃圾回收

  垃圾回收就是回收内存中不再使用的对象。

  步骤有2步:

    1. 查找内存中不再使用的对象

      (1)引用计数法:有一个缺点,不能检测到环的存在

      (2)根搜索算法:通过一系列名为“GC Roots”的对象作为起始点,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的

    2.释放这些对象占用的内存

        (1) 标记-复制 :它将可用内存容量划分为大小相等的两块,每次只使用其中的一块。当这一块用完之后,就将还存活的对象复制到另外一块上面,然后在把已使用过的内存空间一次理掉。它的优点是实现简单,效率高,不会存在内存碎片。缺点就是需要2倍的内存来管理。

      (2) 标记-清理:清除算法分为“标记”和“清除”两个阶段:首先标记出需要回收的对象,标记完成之后统一清除对象。它的优点是效率高,缺点是容易产生内存碎片。

        (3) 标记-整理:标记操作和“标记-清理”算法一致,后续操作不只是直接清理对象,而是在清理无用对象完成后让所有 存活的对象都向一端移动,并更新引用其对象的指针。因为要移动对象,所以它的效率要比“标记-清理”效率低,但是不会产生内存碎片。

      新生代和老生代:

    由于对象的存活时间有长有短,所以对于存活时间长的对象,减少被gc的次数可以避免不必要的开销。这样我们就把内存分成新生代和老年代,新生代存放刚创建的和存活时间比较短的对象,老年代存放存活时间比较长的对象。这样每次仅仅清理年轻代,老年代仅在必要时时再做清理可以极大的提高GC效率,节省GC时间。

  

  java垃圾收集器的历史:

    1. Serial(串行)收集器

    2. Parallel(并行)收集器

    3. CMS(并发)收集器

    4. G1(并发)收集器

二,了解G1

  oracle官方计划在jdk9中将G1变成默认的垃圾收集器,以替代CMS。

  G1的设计原则就是简单可行的性能调休。将新生代,老生代的物理空间划分取消了。

  

  细节:

G1算法将堆划分为若干个区域(Region),它仍然属于分代收集器。不过,这些区域的一部分包含新生代,新生代的垃圾收集依然采用暂停所有应用线程的方式,将存活对象拷贝到老年代或者Survivor空间。老年代也分成很多区域,G1收集器通过将对象从一个区域复制到另外一个区域,完成了清理工作。这就意味着,在正常的处理过程中,G1完成了堆的压缩(至少是部分堆的压缩),这样也就不会有cms内存碎片问题的存在了。

在G1中,还有一种特殊的区域,叫Humongous区域。 如果一个对象占用的空间超过了分区容量50%以上,G1收集器就认为这是一个巨型对象。这些巨型对象,默认直接会被分配在年老代,但是如果它是一个短期存在的巨型对象,就会对垃圾收集器造成负面影响。为了解决这个问题,G1划分了一个Humongous区,它用来专门存放巨型对象。如果一个H区装不下一个巨型对象,那么G1会寻找连续的H分区来存储。为了能找到连续的H区,有时候不得不启动Full GC。

PS:在java 8中,持久代也移动到了普通的堆内存空间中,改为元空间。

     最后,G1提供了两种GC模式,Young GC和Mixed GC,两种都是Stop The World(STW)的。

猜你喜欢

转载自www.cnblogs.com/pzyin/p/9811909.html
今日推荐