一.什么是垃圾回收?

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

  • 内存泄漏监测工具: 这种工具的原理一般是静态代码的扫描,通过扫描程序检测可能出现内存泄露的代码段,然而检测工具难免有疏漏和不足, 只能起到辅助作用。
  • 智能指针:是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. HarmonyOS 实现跑马灯效果
  2. 基于ESP32模块利用检测线圈检测车模停止时间,室内视觉AI裁判系统
  3. MyCat安装,数据导入,以及安装过程中的各种参数配置
  4. MMM for MySQL FAQ
  5. Silverlight简介
  6. 《html5 从入门到精通》读书笔记(一)
  7. 2013电赛总结【西电专用】
  8. python中的字典和集合_Python 字典和集合
  9. 工作流实战_17_flowable 流程实例撤回
  10. 2022年学C++好比49年入国军?
  11. java中蓝色是多少_JAVA几个常见错误简析
  12. 如何卸载Edge/如何降Edge版本
  13. Docker 端口映射到宿主机后, 外网无法通过ip访问对应宿主机端口
  14. 网站制作教程:初学者如何制作网站,有哪些步骤?
  15. Exchange 2003 反垃圾邮件
  16. 不可不学的摄影技巧.1—构图
  17. python 白噪声检验-python之时间序列分析(一)
  18. 3ds max 2014 启动出现 error while registering plugins 怎么修复
  19. Python可视化常用方法和常见问题解决方案
  20. 一起“玩转”微信公众号营销

热门文章

  1. 能模仿韩寒小四写作的神奇递归神经网络(附代码)
  2. python 66:re正则表达式4(全- tcy)
  3. 微信小程序学习记录2(js中数组和对象)
  4. 完整HTML实例网页代码(2)
  5. 快付生态开发积分交易核心源码段
  6. win10系统改变文本的默认打开方式
  7. 学服装设计必看的电影推荐
  8. 006 - CMake 安装动态库并生成 XxxConfig.cmake 文件
  9. echarts进度条
  10. Spring Session 详解