GC入门

作者: 雁宇 | 来源:发表于2018-03-12 11:47 被阅读92次

术语

  • 垃圾(Carbage):需要回收的对象。

  • 根(Root):判断对象是否可被引用的起始点。

GC的三种基本方式

标记清除(Mark and Sweep)- 处理垃圾少的情况

最早开发出的GC算法。其原理是首先从根开始将可能被引用的对象用递归的方式进行标记,然后将没有标记到的对象作为垃圾进行回收。

标记清除算法的处理时间,是和存活对象与对象总数的总和相关的。

作为标记处理清除的变形,还有一种叫做标记压缩(Mark and Compact)的算法,它不是将被标记的对象清除,而是将其不断压缩。

复制收集(Copy and Collection)- 处理垃圾多的情况

标记清除算法有一个缺点,就是在分配了大量对象,而且其中只有一小部分存活的情况下,所消耗的时间会大大超过必要的值,这是因为在清除阶段还需要对大量的死亡对象进行扫描。

复制收集则试图克服这一缺点。其会将从根节点开始被引用的对象复制到另外的空间中,然后,再将复制的对象所能够引用的对象用递归的方式不断复制下去。

和标记相比,将对象复制一份所需的开销则比较大,因此在”存活“对象比例较高的情况下,反而会比较不利。

这种算法的另一个好处是局部性。在复制收集的过程中,会按照对象被引用的顺序将对象复制到新空间中。于是,关系较近的对象被放在距离较近的内存空间中的可能性会提高,这被称为局部性。在局部性高的情况下,内存缓存会更容易高效运作,程序的运行性也能够提高。

引用计数(Reference Count)- 简单,但有致命缺陷

是GC算法中最简单也最容易实现的一种,其会在每个对象中保存该对象的引用计数,当引用发生增减时对计数进行更新,当一个对象的引用计数变为0时,释放其空间。

优点是容易实现,及当对象不再被引用的瞬间就会被释放,没有其他GC算法的长时间中断。

缺点

  • 无法释放循环引用的对象。

  • 必须在引用发生增减时对引用计数做正确的增减。

  • 不适合并行处理。

依然使用引用计数的语言主要有Perl和Python,但它们为了避免循环引用的问题,都配合使用了其他的GC机制。

进一步改良的应用方式

分代回收(Generational GC)- 减少扫描的数目

基本思路是利用了一般性程序所具备的性质,即大部分对象都会在短时间内成为垃圾,而经过一定时间依然存活的对象往往拥有较长的寿命。如果对分配不久,诞生时间较短的“年轻”对象进行重点扫描,应该就可以更有效地回收大部分垃圾。

在分代回收中,对象按照生成时间进行分代,刚刚生成不久的年轻对象划为新生代(Young generation),而存活了较长时间的对象划为老生代(Old generation)。

只扫描新生代对象的回收操作,被称为小回收(Minor GC)。小回收的具体回收步骤如下。

首先从根开始一次常规扫描,找到“存活”对象。这个步骤采用标记清除或者是复制收集算法都可以,不过大多数分代回收的实现都采用了复制收集算法。需要注意的是,在扫描的过程中,如果遇到属于老生代的对象,则不对该对象继续进行递归扫描。这样一来,需要扫描的对象数量就会大幅减少。然后,将第一次扫描后残留下来的对象划分到老生代。具体来说,如果是用复制收集算法的话,只要将复制目标空间设置为老生代就可以了;而用标记清除算法的话,则大多采用在对象上设置某种标志的方式。

虽说老生代区域中的对象一般来说寿命都比较长,但也决不是“不老不死”的。随着程序的运行,老生代区域中的“死亡”对象也在不断增加。为了避免这些死亡的老生代对象白白占用内存空间,偶尔需要对包括老生代区域在内的全部区域进行一次扫描回收。像这样以全部区域为对象的 GC 操作被称为完全回收(Full GC)或者大回收(Major GC)。

分代回收通过减少 GC 中扫描的对象数量,达到缩短 GC 带来的平均中断时间的效果。不过由于还是需要进行大回收,因此最大中断时间并没有得到什么改善。从吞吐量来看,在对象寿命假说能够成立的程序中,由于扫描对象数量的减少,可以达到非常不错的成绩。但是,其性能会被程序行为、分代数量、大回收触发条件等因素大幅度左右。

增量回收(Incremental GC)- 提高实时性

为了维持程序的实时性,不等到 GC 全部完成,而是将 GC 操作细分成多个部分逐一执行。

由于增量回收的过程是分步渐进式的,可以将中断时间控制在一定长度之内。另一方面, 由于中断操作需要消耗一定的时间,GC 所消耗的总时间就会相应增加,正所谓有得必有失。

并行回收(Parallel GC)

通过最大限度利用多 CPU 的处理能力来进行 GC 操作的一种方式

Java中的内存管理

  1. 垃圾回收介绍

  2. 垃圾回收是如何工作的?

  3. 垃圾回收的类别

  4. 垃圾回收监视和分析

参照

  • 松本行弘《代码的未来》

相关文章

  • GC入门

    术语 垃圾(Carbage):需要回收的对象。 根(Root):判断对象是否可被引用的起始点。 GC的三种基本方式...

  • oc 遍历

    标签:ios开发入门 NSArray NSDictionary ​2016年07月30日10:02:31补充:GC...

  • JVM GC调优入门

    JVM GC调优入门 这篇文章会介绍几个常用的调优参数,再通过两个案例介绍如何进行JVM GC调优。阅读这篇文章的...

  • 万字长文把[JVM]从头到尾讲一遍

    第一篇:[JVM入门指南01]内存区域与溢出异常——主要介绍JVM的运行时数据区第二篇:[JVM入门指南02]GC...

  • JVM垃圾收集器

    GC的时机 GC从时机上分为两种:Scavenge GC和Full GC Scavenge GC(Minor GC...

  • java常见垃圾收集器

    常见的有Serial GC、ParNew GC、CMS GC、Parallel GC、G1 GC Serial G...

  • FullGC、MinorGC、STW等常见问题如何解答

    什么是Full GC?minor GC? major GC? STW? minor GC:新生代回收的gc( ST...

  • Spark笔记-001-GC

    我真的不懂Java... GC急速入门 Java对象在内存中的结构 如何确定对象可以被回收java通过引用访问堆中...

  • 内存分配与回收策略

    1 Minor GC+Major GC+Full GC (1)Minor GC:新生代GC。因为Java对象大多都...

  • Go GC

    1、什么是GC?2、为什么会有GC?3、GC的优点?4、GC的缺点?5、Go中的GC历史6、Go中的GC实现原理(...

网友评论

      本文标题:GC入门

      本文链接:https://www.haomeiwen.com/subject/ybiimxtx.html