golang中的gc采用三色标记法。在讲三色标记法之前,先了解一下Mark and Sweep算法,因为Mark and Sweep算法是三个标记法的一个改进版。

Mark and Sweep算法: 停止运行程序,遍历所有被引用的变量,被引用的对象被标记为“被引用”,没有被标记的进行回收。内存单元并不会立刻回收对象,而是将其标记为“不可达”状态。直到到达某个阈值或者到达某个时间间隔后,对其进行垃圾回收。算法分为两部分:标记(Mark)和清理(Sweep)。挂起程序,对所有存活的内存单元进行扫描,标记,确定哪些可以清除。优点是解决了相互引用的缺点,不足是会停止应用程序,当内存单元变量过多时,扫描清除会花很长时间,甚至几百毫秒。

三色标记法:属于标记清除法的一个改进版。起初所有内存对象都在白色的,从根出发标记所有的对象,标记为灰色,并放入一个队列。然后再将灰色队列中的对象取出,将其引用对象标记为黑色。重复此步骤,待灰色对象队列为空时,所有白色对象既为垃圾。最后白色区域内存对象被释放,黑色区域标记为白色,等待下一阶段GC再次扫描。

三色标记法触发有两个条件:第一个是阀值,就是内存扩大一倍时启动GC。第二个是每隔两分钟GC一次。

三色标记法的具体过程

1、GC开始的时候stop the world。对内存中的对象进行扫描。扫描完毕后,start the world。程序继续运行,GC同时开始标记。

2、将线程(goroutine)直接引用的对象标记为灰色,将灰色内存对象标记为黑色。同时将灰色内存对象引用的对象标记为灰色。

3、反复第2步直到灰色区域为空。此时只有黑色和白色区域了。

4、stop the world, again! 利用写屏障机制,将GC扫描时新创建的对象一律标记为灰色,然后变成黑色。

5、将内存对象被标记为白色的进行释放sweep。

6、剩下的内存全部标记为白色,以便下一次GC使用。

如何优化GC

写代码时,如果要考虑GC对性能的影响,那么要避免要用string+操作,改用var buf bytes.Buffer,用buf.WriteString("xxxx")操作。因为没有string+操作都会生成一个新的string,产生多余的内存碎片。还有就是尽量复用小对象,局部变量需要尽量少声名,多个小对象可以放到一个结构体中,这样方便GC扫描。

golang GC(一 原理)的更多相关文章

  1. golang gc 问题(转的)

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

  2. golang ----gc问题

    go程序内存占用大的问题 这个问题在我们对后台服务进行压力测试时发现,我们模拟大量的用户请求访问后台服务,这时各服务模块能观察到明显的内存占用上升.但是当停止压测时,内存占用并未发生明显的下降.花了很 ...

  3. Golang GC 垃圾回收机制详解

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

  4. Go语言GC实现原理及源码分析

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/475 本文使用的 Go 的源码1.15.7 介绍 三色标记法 三色标 ...

  5. JVM 的 工作原理,层次结构 以及 GC工作原理

    JVM Java 虚拟机 Java 虚拟机(Java virtual machine,JVM)是运行 Java 程序必不可少的机制.JVM实现了Java语言最重要的特征:即平台无关性.原理:编译后的 ...

  6. Golang GC原理

    一.内存泄漏 内存泄露,是从操作系统的角度上来阐述的,形象的比喻就是“操作系统可提供给所有进程的存储空间(虚拟内存空间)正在被某个进程榨干”,导致的原因就是程序在运行的时候,会不断地动态开辟的存储空间 ...

  7. JVM垃圾回收(GC)原理

    一.基本垃圾回收算法 1.引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用则增加一个引用计数,删除一个引用则较少一个引用计数.垃圾回收时,只回收引用计数为0 ...

  8. 优秀Java程序员必须了解的GC工作原理(转)

    一个优秀的Java程序员必须了解GC(Garbage Collection 垃圾收集)的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系 ...

  9. 浅析 golang interface 实现原理

    interface 在 golang 中是一个非常重要的特性.它相对于其它语言有很多优势: duck typing.大多数的静态语言需要显示的声明类型的继承关系.而 golang 通过 interfa ...

随机推荐

  1. 123457123456---com.threeObj03.FanPaiZi01--- 记忆翻牌儿童

    com.threeObj03.FanPaiZi01--- 记忆翻牌儿童

  2. win7下docker环境安装

    最近公司涉及到对docker容器引擎的使用,所以就在网上各种搜索,由于是win7系统,所以在使用上更是麻烦,遇到各种错误就是无法成功启动docker,经过两天的各种尝试下,终于安装成功,在此记录一下使 ...

  3. 项目中学习ReactiveCocoa的使用方法

    一.注册控制器 控制器上的一个属性 @property (weak, nonatomic) IBOutlet UIBarButtonItem *signInBtn; 在 viewDidLoad 方法中 ...

  4. IIS添加对ashx文件的支持

    IIS添加对ashx文件的支持 第一步:每个网站都有个“处理程序映射”,用于添加对各种文件的处理程序 第二步:进入“处理程序映射",可以看到对各种文件的处理程序列表,其中就有对ashx文件的 ...

  5. 【Leetcode_easy】1078. Occurrences After Bigram

    problem 1078. Occurrences After Bigram 题意 solution: class Solution { public: vector<string> fi ...

  6. iOS面霸计划(难度)

    一.面试题 1.Xcode项目的目录结构是怎么分组的? 2.简单介绍下在真机上调试开发证书申请流程. 3.按Home键时,怎么保存程序运行状态 4.当程序运行过程中,按下home键以后,ios程序会调 ...

  7. 给引入页面的js和css资源加上版本号,防止浏览器缓存资源

    最近因为在做前端开发的相关工作,每次发布新版本以后,不到5分钟,测试童鞋一个接一个的抱怨说BUG根本就没有修改,这个时候你说的最多的话就是“清缓存!!清页面缓存!!你没有清缓存!!你清理了页面缓存就对 ...

  8. idea查看一个接口的子接口或实现类的快捷键

    ctrl+h 先选中类或接口,再按ctrl+h

  9. Ubuntu18.04命令行安装mysql未提示输入密码,修改mysql默认密码

    Ubuntu18.04命令行安装mysql未提示输入密码,修改mysql默认密码 mysql默认密码为空 但是使用mysql -uroot -p 命令连接mysql时,报错ERROR 1045 (28 ...

  10. 解决ffmpeg执行报错“ffmpeg: error while loading shared libraries: libavdevice.so.58: cannot open shared object file: No such file or directory”的问题

    问题现象: 执行ffmpeg命令后报错: ffmpeg: error : cannot open shared object file: No such file or directory 出问题的环 ...