一.什么是垃圾回收?

内存泄漏过去一般的发现的方式:

  • 内存泄漏监测工具: 这种工具的原理一般是静态代码的扫描,通过扫描程序检测可能出现内存泄露的代码段,然而检测工具难免有疏漏和不足, 只能起到辅助作用。
  • 智能指针:是C++中引入的自动内存管理方法,通过拥有自动内存管理功能的指针对象来引用对象,是程序员不太关注内存的释放,而达到内存自动释放的目的。这种方法是采用最广泛的做法,但是对于程序员来说有一定的学习成本,而且一旦有忘记使用的场景仍然会有内存泄露。
    为了解决这方面的问题,后来开发出来的几乎所有的语言都有语言层面的自动内存管理-也就是语言的使用者只关注内存的申请而不关注内存的释放,内存释放由虚拟机或者运行时来自动管理。而这种对于不再使用的内存资源进行自动回收的过程就被称为垃圾回收。

二.常见的垃圾回收方法

  • 引用计数
    这是最简单的一种垃圾回收算法,和之前提到的智能指针异曲同工。对每一个对象维护一个引用计数,当引用该对象的对象被销毁或者更新,被引用对象的引用计数自动减1,当被引用对象被创建或者被其他对象引用时引用计数自动增1,当引用计数为0时,立即回收该对象。
    这种方法的优点是实现简单,并且回收的速度很及时。这种算法在内存比较紧张和实时性比较高的系统中应用比较广泛,如ios的cococa框架,php、python等,简单引用计数也有明显的缺陷:

    频繁更新引用计数降低了性能,一种简单的解决方法就是编译器将相邻的引用计数更新操作合并到一次更新,还有一种方法是针对频繁发生的临时变量引用不进行计数,而是在引用达到0时通过扫描堆栈确认是否还有临时对象引用而决定是否释放
    循环引用问题,当对象中发生循环引用时引用链中的对象都无法得到释放,最明显的办法是避免出现循环引用,如cocoa中引入了strong类型和week类型的两种指针类型,或者系统检测循环引用并且打破循环链。当然也增加了垃圾回收的复杂度。

  • 标记-清除
    该方法分为两步,标记从根变量开始迭代得遍历所有被引用的引用的对象,对能够通过引用遍历访问到的对象都进行标记为“被引用”;标记完成功后进行删除操作,对没有标记过的内存进行回收(回收同时可能伴有碎片整理处理),这种发放解决了引用计数的不足,但是也有比较明显的问题:每次启动垃圾回收都会暂停所有正常代码执行,回收时系统响应能力大大降低,当然后续也出现了很多mark和sweep算法的变种(如三色标记)优化了这个问题。

  • 分代回收
    经过大量实际观察得知,在面向对象编程中,大多数对象的生命周期都是比较短暂的。分代收集器的基本思想是将堆换分成两个或者多个称为代的空间。新创建的对象存放称为新生代中,随着垃圾回收的重复执行,生命周期较长的对象会被提升到老年代中。因此新生代回收和老年代回收两种不同的垃圾回收方式应用而生,分别用于对各自空间中的对象执行垃圾回收。新生代垃圾回收的速度非常快,比老年代快几个数量级,即使新生代垃圾回收的频率很高,执行效率也仍然比老年代垃圾回收强,这是因为大对数对象的生命周期都很短,根本无需提升到老年代。

三.Go的垃圾回收器

GO语言垃圾回收总体使用的是经典的mark和sweep算法

  • 1.3版本以前,golang的垃圾回收算法都非常简陋,然后其性能也广被诟病:go runtime在一定条件下(内存超过阈值或定期如2min),暂停所有任务的执行,进行mark&sweep操作,操作完成后启动所有任务的执行。在内存使用较多的场景下,go程序在进行垃圾回收时会发生非常明显的卡顿现象(Stop The World)。在对响应速度要求较高的后台服务进程中,这种延迟简直是不能忍受的!这个时期国内外很多在生产环境实践go语言的团队都或多或少踩过gc的坑。当时解决这个问题比较常用的方法是尽快控制自动分配内存的内存数量以减少gc负荷,同时采用手动管理内存的方法处理需要大量及高频分配内存的场景。
  • 1.3版本开始go team开始对gc性能进行持续的改进和优化,每个新版本的go发布时gc改进都成为大家备受关注的要点。1.3版本中,go runtime分离了mark和sweep操作,和以前一样,也是先暂停所有任务执行并启动mark,mark完成后马上就重新启动被暂停的任务了,而是让sweep任务和普通协程任务一样并行的和其他任务一起执行。如果运行在多核处理器上,go会试图将gc任务放到单独的核心上运行而尽量不影响业务代码的执行。go team自己的说法是减少了50%-70%的暂停时间。
  • 1.4版本(当前最新稳定版本)对gc的性能改动并不多。1.4版本中runtime很多代码取代了原生c语言实现而采用了go语言实现,对gc带来的一大改变是可以是实现精确的gc。c语言实现在gc时无法获取到内存的对象信息,因此无法准确区分普通变量和指针,只能将普通变量当做指针,如果碰巧这个普通变量指向的空间有其他对象,那这个对象就不会被回收。而go语言实现是完全知道对象的类型信息,在标记时只会遍历指针指向的对象,这样就避免了C实现时的堆内存浪费(解决约10-30%)。
  • 1.5版本go team对gc又进行了比较大的改进(1.4中已经埋下伏笔如write barrier的引入),官方的主要目标是减少延迟。go 1.5正在实现的垃圾回收器是“非分代的、非移动的、并发的、三色的标记清除垃圾收集器”。分代算法上文已经提及,是一种比较好的垃圾回收管理策略,然1.5版本中并未考虑实现;我猜测的原因是步子不能迈太大,得逐步改进,go官方也表示会在1.6版本的gc优化中考虑。同时引入了上文介绍的三色标记法,这种方法的mark操作是可以渐进执行的而不需每次都扫描整个内存空间,可以减少stop the world的时间。 由此可以看到,一路走来直到1.5版本,go的垃圾回收性能也是一直在提升,但是相对成熟的垃圾回收系统(如java jvm和javascript v8),go需要优化的路径还很长(但是相信未来一定是美好的~)。

Golang 垃圾回收相关推荐

  1. golang垃圾回收概述

    golang垃圾回收 golang的垃圾回收机制已经迭代过好几次了,主要的几个演进过程如下: v1.0版本中使用标记和清除算法,需要再整个gc过程中暂定程序. V1.5版本中实现了三色标记清除的并发垃 ...

  2. Golang——垃圾回收GC(2)

    1 垃圾回收中的重要概念 1.1 定义 In computer science, garbage collection (GC) is a form of automatic memory manag ...

  3. 图示Golang垃圾回收机制

    垃圾回收概念 程序创建对象等引用类型实体时会在虚拟内存中分配给它们一块内存空间,如果该内存空间不再被任何引用变量引用时就成为需要被回收的垃圾.操作系统会记录一个进程运行时的所占用的内存.CPU和寄存器 ...

  4. Golang垃圾回收机制(一)

    原文: http://legendtkl.com/2017/04/28/golang-gc/ 1. Golang GC 发展 Golang 从第一个版本以来,GC 一直是大家诟病最多的.但是每一个版本 ...

  5. Golang——垃圾回收GC

    Go 垃圾回收原理 Golang源码探索(三) GC的实现原理 引用计数:对每个对象维护一个引用计数,当引用该对象的对象被销毁时,引用计数减1,当引用计数器为0是回收该对象. 优点:对象可以很快的被回 ...

  6. Golang 垃圾回收剖析

    1. Golang GC 发展 Golang 从第一个版本以来,GC 一直是大家诟病最多的.但是每一个版本的发布基本都伴随着 GC 的改进.下面列出一些比较重要的改动. v1.1 STW v1.3 M ...

  7. Golang 垃圾回收机制

    1. Golang GC 发展 Golang 从第一个版本以来,GC 一直是大家诟病最多的.但是每一个版本的发布基本都伴随着 GC 的改进.下面列出一些比较重要的改动. v1.1 STW v1.3 M ...

  8. Golang垃圾回收机制详解

    Golang 从第一个版本以来,GC 一直是大家诟病最多的.但是每一个版本的发布基本都伴随着 GC 的改进.下面列出一些比较重要的改动. v1.1 STW v1.3 Mark STW, Sweep 并 ...

  9. Golang 垃圾回收机制详解

    摘要 在实际使用 go 语言的过程中,碰到了一些看似奇怪的内存占用现象,于是决定对go语言的垃圾回收模型进行一些研究.本文对研究的结果进行一下总结. 什么是垃圾回收? 曾几何时,内存管理是程序员开发应 ...

最新文章

  1. 用开关控制蜂鸣器_室内照明控制系统的调试与检修
  2. 图的存储结构与操作--C语言实现
  3. 字符编码以及文件处理
  4. 动画延迟效果css,每个子元素都有延迟的CSS动画
  5. [转载]CLR怎样实现虚方法的多态调用(2)
  6. php字符串转换mysql_在PHP中将字符串转换为MySQL时间戳格式
  7. DCF:A Dataflow-Based Collaborative Filtering Trainging Algorithm
  8. python3 实现对比conf 文件差异
  9. TensorFlow中Variable()和get_variable()
  10. 交互设计中Web UI与手机UI的区别
  11. Docker Compose 引用环境变量
  12. 测视力距离5米还是3米_高度近视眼怎么恢复视力?
  13. 小说阅读器未能连接服务器怎么办,小强小说阅读器无法加载小说章节的解决方法...
  14. 阮一峰ES6入门学习笔记~~变量的解构赋值
  15. teamtalk mysql.h_新版TeamTalk完整部署教程
  16. 商用密码应用安全性评估过程学习指南
  17. 2021年安全生产模拟考试(全国特种作业操作证电工作业-防爆电气模拟考试题库二)安考星
  18. win10 u盘 修复计算机,u盘启动修复Win10引导文件丢失的方法
  19. 【分享】常用JS(2)
  20. 跟着团子学SAP EPPM: CPM主要底表

热门文章

  1. 行测-言语类题目总结
  2. HISIV3519交叉编译nginx服务器
  3. Excel中的vlookup函数多条件查找引用
  4. mybatisPlus更新字段值为null
  5. LVM与磁盘配额原理及配置
  6. Android 项目必备(三十一)-->一个优秀的 APP 从建项目开始
  7. python退出语句_python退出命令
  8. Python主要用途有哪些?学完Python可以做什么?
  9. DT清单,供参考,表格样式
  10. tftp服务器从交换机上下载配置命令_若要将交换机中的映像文件备份到TFTP服务器,其配置命令为( )。(2分)...