An Introduction to Garbage Collection(垃圾回收简介)
团队项目中用Go的地方越来越多,最近打算在业余时间好好看看Golang的虚拟机实现。像Java/C#/Python一样,Go的优势之一就是将开发人员从繁重的内存管理中解放 出来,本文对编程语言中常见的垃圾回收技术做一个简要的笔记。
1 Introduction
垃圾回收是一种自动的内存管理技术,它的主要任务就是防止应用程序无休止地向操作系统或Glibc不停地申请内存。通常的做法是将程序不再使用的内存释放给操作 系统或运行时环境,或者回收后重复利用。垃圾回收是John McCarthy同学于1959年在Lisp语言中发明。 由于引入了额外的工作,垃圾回收不可避免地会影响应用进程的实际执行时间,而且它的实现对程序性能有较大的影响。垃圾回收通常都指内存资源的回收,一些其他 的资源,如网络连接、数据库连接、文件描述符等不是垃圾回收的管辖范围。
2 Principles
垃圾回收的基本原则是:
- 找出应用进程不再需要的数据对象
- 回收这些对象占用的内存
3 Advantages
垃圾回收能有效地减少因为管理内存引起的Bug:
- 悬挂指针
- 多次释放同一块内存
- 防止内存泄漏
4 Disadvantages
事务总有两面性,垃圾回收不可避免地会带来如下缺陷:
- 消耗系统的计算资源。因为垃圾回收需要对已分配的对象做额外的处理(如增加引用计数等),而且在回收算法会相当耗时。有研究称,垃圾回收会占用五倍于传统内存管理的时间。
- 垃圾回收所消耗的时间不可测。对于一些实时性要求较高的系统来说,这简直是噩梦。
- 如果在有自动垃圾回收的系统中还允许手动回收内存资源。这会是垃圾回收变得更加复杂和扑朔迷离。
5 常见的垃圾回收技术
5.1 跟踪式垃圾回收
跟踪式垃圾回收是最常用的垃圾回收技术。它的主要原则是从程序栈的若干个根对象出发,构造一个可达链,对于那些不可达的内存对象,做回收。 如果一个内存对象有被程序中的至少一个变量引用(直接指向或间接指向),则认为该对象可达,否则认为该对象不可达,可以被垃圾回收。
5.1.1 基本算法
- 标记清除(mark-and-sweep)
基本思路是遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。它最大的问题是无法处理 循环引用的问题,而且在GC时,需要程序中断一段时间来清理内存。
- 三色标记法(triple-color-marking)
应用程序的内存对象会被分发到三个集合中,它们分别是(下面将内存对象统称为元素):
- The Write Set(白色集合)。这个集合中的元素是要被回收的
- The Black Set(黑色集合)。这个集合中的元素都是引用关系图中Root指向的元素,它们与白色集合中的元素没有任何引用关系。在做垃圾回收时,这个集合中的元素时不会被
回收的,在很多系统的实现中,这个集合在系统初始化时是空的。
- The Gray Set(灰色集合)。这个集合中的元素是被Root直接指向的。因为这些元素是Root直接指向的,所以它们在垃圾回收的时候会被移到黑色集合中。通常情况下,在系统初始化的时候,灰色集合中的元素是被Root直接指向的元素,其他所有元素都在白色集合中。 系统中所有的元素在同一时刻只能存在于一个集合中。回收算法是:
+从灰色集合中选取一个元素
+将这个元素移入黑色集合中,并且将它指向的所有白色集合中的元素都移入灰色集合中
+重复上面的步骤,直到灰色集合为空
此时,白色集合中的所有元素是被标记为没有任何变量引用它(直接引用或者间接引用)的元素的集合,它们是在垃圾回收时被清理掉的。 因为不能从Root直接可达的元素都在白色集合中,而且元素只能从白色集合移动到灰色集合,或者从灰色集合移动到黑色集合。这就保证了白色集合中的元素没有一个是黑色集 合中的元素指向的,所以在灰色集合为空时,我们可以安全地将白色集合中的元素删除。
三色标记法的一个非常重要的优势就是可以在系统运行时执行。可以在分配内存对象时将它们标记,当白色集合的容量到达一定规模时,可以启动垃圾回收算法。 关于三色标记法的详细信息见维基百科
5.2 引用计数垃圾回收
基本思路是为每个对象加一个计数器,记录指向这个对象的引用数量。每次有一个新的引用指向这个对象,计数器加一;反之每次有一个指向这个对象引用被置空或者指向其他 对象,计数器减一。当计数器变为 0 的时候,自动删除该对象。 引用计数的优点是当某个对象的引用计数减为0时,它会马上被回收,不会对系统带来额外的中断,同时,因为此时该对象可能仍然在Cache中,所以它不会对Cache和虚拟内存 系统带来额外的开销。 但是它有不少缺点:一是循环引用计数的问题,有一些算法和方法专门来处理循环引用计数;二是为每个内存对象增加一个计数,会增大对象大小;三是,如果该内存对象 如果被多个线程或进程使用,那么它们同时增加和减少引用计数时要考虑互斥问题,这也会给系统带来不小的开销。
5.3 分代垃圾回收
通常情况下,又很多刚分配的临时对象,有可能马上就需要被回收;反之,那些长时间没有被回收的对象,它们的生命周期往往很长,对其频繁地回收没有任何意义。 分代垃圾回收器管理若干个生命周期不同的对象集合,刚分配的对象在生命周期较短的集合中,垃圾回收时优先回收生命周期较短的集合中的元素,然后把存活下来的元素移动 到生命周期较长的集合中。。。。以此类推。
5.4 对象使用类型分析
对于一些局部对象,没有必要在堆上分配它们,拥有垃圾回收功能的系统可以将局部对象在栈上分配,当函数调用返回时,这些临时对象会被自动释放。
An Introduction to Garbage Collection(垃圾回收简介)的更多相关文章
- 【python进阶】Garbage collection垃圾回收1
前言 GC垃圾回收在python中是很重要的一部分,同样我将分两次去讲解Garbage collection垃圾回收,此篇为Garbage collection垃圾回收第一篇,下面开始今天的说明~~~ ...
- 【python进阶】Garbage collection垃圾回收2
前言 在上一篇文章[python进阶]Garbage collection垃圾回收1,我们讲述了Garbage collection(GC垃圾回收),画说Ruby与Python垃圾回收,Python中 ...
- JVM-5-GC(Garbage Collection) 垃圾回收机制
GC(Garbage Collection) 垃圾回收机制 什么是垃圾回收机制 垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能. ...
- Java GC系列(1):Java垃圾回收简介
本文由 ImportNew - 好好先生 翻译自 javapapers. Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Ja ...
- JavaScirpt 的垃圾(garbage collection)回收机制
一.垃圾回收机制—GC Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存. 原理:垃圾收集器会定期(周期性 ...
- 【原创】GC/垃圾回收简介
GC简介 1 GC机制 1.1 对象 从计算机的角度,装有数据的内存空间 1.2 作用 将内存垃圾的释放自动化 1.3 本质 将已经引用不到的对象视为死亡,将死亡的对象找出来并且作为垃圾进行回收 2 ...
- Java垃圾回收简介
Java关键术语 JavaAPI:一系列帮助开发者创建Java应用程序的封装好的库. Java 开发工具包 (JDK):一系列工具帮助开发者创建Java应用程序.JDK包含工具编译.运行.打包.分发和 ...
- 【荐】PHP Session和Cookie,Session阻塞,Session垃圾回收,Redis共享Session,不推荐Memcached保存Session
什么是 Session 在 web 应用开发中,Session 被称为会话.主要被用于保存某个访问者的数据. 由于 HTTP 无状态的特点,服务端是不会记住客户端的,对服务端来说,每一个请求都是全新的 ...
- php--session垃圾回收机制
在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾.PHP会将其在内存中销毁:这是PHP的GC垃圾处理机制,防止内存溢出. GC的工作就是扫描所有的Session信息,用当前时间减去sessi ...
随机推荐
- XMPP系列2:如何掌握XMPP协议
michaely 回答于 2012-08-07 08:34 举报我要说的是:1.任何一个协议想学习并熟练掌握,都不是一天两天的事情.2.XMPP协议现在已经有很多成熟的架构和客户端,无需重新造轮子.3 ...
- 流媒体选择Nginx是福还是祸?
CDN,视频云,已经“僧多粥少” 视频直播的持续升温,无意间也让带宽生意的争夺变得异常残酷.一时间,各种云计算.CDN.视频云提供商都在视频尤其是直播上投入重兵,揭竿而起的新生起义军们也正马不停蹄的赶 ...
- 删除windows系统中以前的设备(比如以前的网卡)或驱动的方法
1.在“开始”菜单单击“运行”,然后在“运行”对话框中输入“CMD”命令打开命令提示符窗口:2.在提示符窗口中输入“Set devmgr_show_nonpresent_devices=1”并回车:3 ...
- 错误名称:EntityCommandExecutionException
错误名称:EntityCommandExecutionException 错误时间:2015/9/22 11:13:34 错误消息:执行命令定义时出错.有关详细信息,请参阅内部异常. 堆栈信息: 在 ...
- 搭建mongodb集群(副本集+分片)
搭建mongodb集群(副本集+分片) 转载自:http://blog.csdn.net/bluejoe2000/article/details/41323051 完整的搭建mongodb集群(副本集 ...
- Java Split以竖线作为分隔符
今天用到了Java中的Split函数,要以“|”作为分割符,当输入竖线时,发现出错,这个问题应该很久前就遇到过,不过太长时间就给忘了! 网上一搜,就找到了答案,这是因为split里面有两个参数,其中一 ...
- jarsigner 签名android apk
1.查看签名: jarsigner -verify app_signed.apk 查看是否签名,如果已经签名会打印 "jar verified". jarsigner -verif ...
- oracle 中触发器增加存储过程commit问题
触发器无需commit也不能写commit触发器和触发它的DML是同一个事务DML提交了,触发器的操作也提交了,要不就一起回滚了 当然,如果你一定要在触发器里写COMMIT那就用自治事务相当于一个事务 ...
- Unity3D]引擎崩溃、异常、警告、BUG与提示总结及解决方法
此贴会持续更新,都是项目中常会遇到的问题,总结成贴,提醒自己和方便日后检查,也能帮到有需要的同学. 若各位有啥好BUG好异常好警告好崩溃可以分享的话,请多多指教.xuzhiping7#qq.com. ...
- English Metric Units and Open XML
English Metric Units and Open XML 在Open XML里使用了English Metric Units(EMUs)来作为度量单位.比如 public class Ext ...