本页使用了标题或全文手工转换

垃圾回收 (计算机科学)

维基百科,自由的百科全书
跳到导航 跳到搜索

垃圾回收(英语:Garbage Collection,缩写为GC),在计算机科学中是一种自动的存储器管理机制。当一个电脑上的动态存储器不再需要时,就应该予以释放,以让出存储器,这种存储器资源管理,称为垃圾回收。垃圾回收器可以让程序员减轻许多负担,也减少程序员犯错的机会。垃圾回收最早起源于LISP语言。[1][2]当前许多语言如SmalltalkJavaC#D语言都支持垃圾回收器。

特征[编辑]

垃圾回收器有两个基本的原理:

  1. 考虑某个对象在未来的程序运行中,将不会被访问。
  2. 向这些对象要求归回存储器。

分类[编辑]

收集器实现[编辑]

  • 引用计数收集器
最早期的垃圾回收实现方法,通过对数据存储的物理空间附加多一个计数器空间,当有其他数据与其相关时则加一,反之相关解除时减一,定期检查各储存对象的计数器,为零的话则认为已经被抛弃而将其所占物理空间回收。是最简单的实现,但存在无法回收循环引用的存储对象的缺陷。
  • 跟踪收集器
近现代的垃圾回收实现方法,通过定期对若干根储存对象开始遍历,对整个程序所拥有的储存空间查找与之相关的存储对象和没相关的存储对象进行标记,然后将没相关的存储对象所占物理空间回收。

回收算法[编辑]

基于其标记和回收行为,又分为若干细致方法。

  • 标记-清除
先暂停整个程序的全部运行线程,让回收线程以单线程进行扫描标记,并进行直接清除回收,然后回收完成后,恢复运行线程。这样会导致大量零碎的空闲空间碎片,和使大容量对象不容易获得连续的内存空间,而造成空间浪费。
  • 标记-压缩
和“标记-清除”相似,不同的是,回收期间同时会将保留的存储对象搬运汇集到连续的内存空间。从而集成空闲空间。
  • 复制
需要程序将所拥有的内存空间分成两个部分。程序运行所需的存储对象先存储在其中一个分区(定义为“分区0”)。同样暂停整个程序的全部运行线程后,进行标记后,回收期间将将保留的存储对象搬运汇集到另一个分区(定义为“分区1”),完成回收,程序在本次回收后将接下来产生的存储对象会存储到“分区1”。在下一次回收时,两个分区的角色对调。
  • 增量回收器
需要程序将所拥有的内存空间分成若干分区。程序运行所需的存储对象会分布在这些分区中,每次只对其中一个分区进行回收操作,从而避免程序全部运行线程暂停来进行回收,允许部分线程在不影响回收行为而保持运行,并且降低回收时间,增加程序响应速度。
  • 分代
由于“复制”算法对于存活时间长,大容量的储存对象需要耗费更多的移动时间,和存在储存对象的存活时间的差异。需要程序将所拥有的内存空间分成若干分区,并标记为年轻代空间和年老代空间。程序运行所需的存储对象会先存放在年轻代分区,年轻代分区会较为频密进行较为激进垃圾回收行为,每次回收完成幸存的存储对象内的寿命计数器加一。当年轻代分区存储对象的寿命计数器达到一定阈值或存储对象的占用空间超过一定阈值时,则被移动到年老代空间,年老代空间会较少运行垃圾回收行为。一般情况下,还有永久代的空间,用于涉及程序整个运行生命周期的对象存储,例如运行代码、数据常量等,该空间通常不进行垃圾回收的操作。
通过分代,存活在局限域,小容量,寿命短的存储对象会被快速回收;存活在全局域,大容量,寿命长的存储对象就较少被回收行为处理干扰。

实现[编辑]

GC的来源可能是由编程语言本身内置(如Java、C#);或是经由外面的库所提供,而非建制于语言内部,例如贝姆垃圾收集器就是一种可支持C/C++语言的自动存储器管理工具。

现今的GC(如Java.NET)使用分代收集(generation collection),依照对象存活时间的长短使用不同的垃圾收集算法,以达到最好的收集性能。

以Java为例,整个Java堆可以切割成为三个部分:

  1. Young:
    1. Eden:存放新生对象。
    2. Survivor:存放经过垃圾回收没有被清除的对象。
    3. semi-Spaces:和Survivor做Copying collection。
  2. Tenured:对象多次回收没有被清除,则移到该区块。
  3. Perm:存放加载的类别还有方法对象。

Java不同的世代使用不同的GC算法。

  1. Minor collection:
    YOUNG世代使用将Eden还有Survivor内的数据利用semi-space做复制收集(Copying collection),
    并将原本Survivor内经过多次垃圾收集仍然存活的对象移动到Tenured。
  2. Major collection则会进行Minor collection,Tenured世代则进行标记压缩收集。

参见[编辑]

参考文献[编辑]

Template:约翰·麦卡锡