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 ...
随机推荐
- 使用eclipse JDT compile class,解决 无法确定 X 的类型参数;对于上限为 X,java.lang.Object 的类型变量 X,不存在唯一最大实例
ant 命令行方式执行build javac编译class出现 泛型无法转换 无法确定 <X>X 的类型参数:对于上限为 X,java.lang.Object 的类型变量 X,不存在唯一最 ...
- spring发送邮件(多人接收或抄送多少带附件发送)
系统中的附件分享功能界面 抄送多个效果图 多个接收者效果图 抄送多人带附件源码 多个接收者带附件源码
- 【原】MyEclipse8.5集成Tomcat7时启动错误:Exception in thread “main” java.lang.NoClassDefFoundError
解决方法: MyEclipse->Window->Preferences->MyEclipse->Servers->Tomcat->Tomcat 6.x->L ...
- isInstance和isAssignableFrom的用法
String str = ""; Object o = new Object(); System.out.println(String.class.isInstance(o)); ...
- 让Windows Server 2008 + IIS 7+ ASP.NET 支持10万并发请求
原文:http://www.cnblogs.com/dudu/archive/2009/11/10/1600062.html 今天下午17点左右,博客园博客站点出现这样的错误信息: Error Sum ...
- SQL语句转摘
http://www.cnblogs.com/Olive116/p/3271706.html 收藏没有用,来收到留链接
- Linux下动态链接库 与gcc 选项
-L 编译时查找动态链接库的路径 -lxxx(小写) e.g -lcudart = link libcudart.so , -I(大写) 头文件的路径 -rpath (-R), 编译时指定链接 ...
- SQLServer 获得所有表结构(包括表名及字段)
then d.name else null end) 表名, a.colorder 字段序号,a.name 字段名, ( then '√'else '' end) 标识, (case when (SE ...
- Microsoft 2013 新技术学习笔记 一
有几年没有关注技术了,最近有点时间想把技术重新捡起来,借着重构手上的一个后台管理框架的机会将微软新的几种技术全部应用一下,从目的上来讲并没有希望能对涉及的技术有很深入的了解,所以这个系列的文章(篇幅不 ...
- Objective-C之类和对象
http://www.cnblogs.com/kenshincui/p/3861302.html