当前位置: 首页 > news >正文

An Introduction to Garbage Collection(垃圾回收简介)

 

  • 1. Introduction
  • 2. Principles
  • 3. Advantages
  • 4. Disadvantages
  • 5. 常见的垃圾回收技术
    • 5.1. 跟踪式垃圾回收
      • 5.1.1. 基本算法
    • 5.2. 引用计数垃圾回收
    • 5.3. 分代垃圾回收
    • 5.4. 对象使用类型分析
  • 6. 参考

团队项目中用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 基本算法

 
  1. 标记清除(mark-and-sweep)

    基本思路是遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。它最大的问题是无法处理 循环引用的问题,而且在GC时,需要程序中断一段时间来清理内存。

  2. 三色标记法(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 对象使用类型分析

对于一些局部对象,没有必要在堆上分配它们,拥有垃圾回收功能的系统可以将局部对象在栈上分配,当函数调用返回时,这些临时对象会被自动释放。

6 参考

+ 维基百科 

+ 知乎

Author: Cobbliu

Created: 2015-04-09 Thu 00:10

Emacs 24.4.1 (Org mode 8.2.10)

Validate

 
 

相关文章:

  • Cookie与Session的区别
  • LINUX 中实现逻辑卷、自动挂载
  • 关于OSC项目演示平台maven的一点疑问
  • 关于DatagramSocket中connet()方法和getInetAddress()方法返回null的说明
  • 通过调用文摘列表API获取文摘
  • 如何在LLDB下排查message sent to deallocated instance问题
  • 提高tomcat的并发能力
  • 对Oracle数据库坏块的理解
  • Delphi 中Format的字符串格式化使用说明(转)
  • 经典问题回忆
  • iOS设计指南
  • lnmp环境安装(1)-linux(centos)系统安装
  • 基于MyBatis3.0.6的基本操作介绍
  • hdu4407 n(n=400000)个数,a[i]=i,m个询问及更改(m=1000),更改某个位置的数,询问区间与这个数互质数的和:容斥/离线...
  • 血的教训---工作中注意的事项(未完)
  • 【mysql】环境安装、服务启动、密码设置
  • AHK 中 = 和 == 等比较运算符的用法
  • CAP 一致性协议及应用解析
  • java取消线程实例
  • PHP的类修饰符与访问修饰符
  • python 装饰器(一)
  • rc-form之最单纯情况
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • 阿里云前端周刊 - 第 26 期
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 从0到1:PostCSS 插件开发最佳实践
  • 计算机常识 - 收藏集 - 掘金
  • 前端路由实现-history
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 温故知新之javascript面向对象
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​水经微图Web1.5.0版即将上线
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (八)Spring源码解析:Spring MVC
  • (二)PySpark3:SparkSQL编程
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)计算机毕业设计ssm电影分享网站
  • (附源码)计算机毕业设计高校学生选课系统
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (一)Linux+Windows下安装ffmpeg
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .Net FrameWork总结
  • .Net MVC + EF搭建学生管理系统
  • .net开发时的诡异问题,button的onclick事件无效
  • .NET文档生成工具ADB使用图文教程
  • @Autowired和@Resource装配
  • @DataRedisTest测试redis从未如此丝滑
  • @Pointcut 使用
  • [1181]linux两台服务器之间传输文件和文件夹
  • [20171113]修改表结构删除列相关问题4.txt