[每周一更]-(第50期):Go的垃圾回收GC

在这里插入图片描述

参考文章:

  • https://juejin.cn/post/7111515970669117447
  • https://draveness.me/golang/docs/part3-runtime/ch07-memory/golang-garbage-collector/
  • https://colobu.com/2022/07/16/A-Guide-to-the-Go-Garbage-Collector/
  • https://liangyaopei.github.io/2021/01/02/golang-gc-intro/
  • https://xargin.com/impl-of-go-gc/
  • https://www.bookstack.cn/read/qcrao-Go-Questions/spilt.5.GC-GC.md

什么是GC?

Go语言的垃圾回收机制Garbage Collection,简称 GC

在传统编程语言中我们需要关注对象的分配位置,要自己去选择对象分配在堆还是栈上,
但在 Go 这门有 GC 的语言中,集成了逃逸分析功能,帮助我们自动判断对象应该在堆上还是栈上,可以使用 go build -gcflags="-m" 来观察逃逸分析的结果

GC的原理是什么?

Go语言的垃圾回收器采用了并发三色标记清除算法(Concurrent Tri-Color Mark-And-Sweep),(Stop-the-World,简称STW,指的是GC事件发生过程中,会产生应用程序的停顿。)尽可能减少STW(stop the world)时间,
以降低吞吐为代价换取低延迟,实现了高效的垃圾回收。
标记清除算法的基本原理是,垃圾回收器将所有的存活对象标记为“活”的,未被标记的对象则被认为是垃圾。经典的标记清除算法通常分为两个阶段:

  • 标记阶段:垃圾回收器从根对象开始,遍历所有可达对象,并将它们标记为“活”的。
  • 清除阶段:垃圾回收器从堆的起始地址开始遍历,将未被标记的对象清除,回收内存。

Go语言的垃圾回收器采用了三色标记法(Tri-Color Marking),将堆上的内存对象分为三种颜色

  • 白色:未被标记为“活”的对象,是潜在的垃圾,后续可能会被GC回收。
  • 灰色:待扫描的对象,当扫描某个灰色对象时,GC会将其标记为黑色,然后将该对象指向的所有对象都标记为灰色,待后续标记。
  • 黑色:被标记为“活”的对象,在这轮GC中不会被回收。

垃圾回收器开始工作时不存在黑色对象,垃圾回收器会将根对象标记为灰色,并从根对象(通常是栈对象和全局对象)开始遍历。垃圾回收器会将灰色对象标记为黑色,
并将该对象指向的对象标记为灰色。垃圾回收器重复这个过程,直到所有可达对象都被标记为黑色。最后,垃圾回收器清除所有未被标记为黑色的对象,即清除所有白色对象。

GC如何优化?

优化GC的开销是提高系统性能和响应速度的重要手段。

缩短STW时间

Go GC触发时机大体分为三种:

  • 手动触发:调用runtime.GC()
  • 常规触发:Target heap memory = Live heap + (Live heap + GC roots) * GOGC / 100
  • sysmon后台周期性强制触发GC
减少堆内存的分配和释放

GC开销大的根源在于heap object多,Go的每轮GC都是FullGC,每轮都要将所有heap object标记(mark)一遍,
即便大多数heap object都是长期alive的,因此,一个直观的降低GC开销的方法就是减少heap object的数量,即减少alloc。

  • 把小对象聚合到一个结构体中,然后做一次分配即可
  • 内存空间重用,如:sync.Pool

常见的GC

  • 引用计数法
    根据对象自身的引用计数来回收,当引用计数归零时进行回收,但是计数频繁更新会带来更多开销,且无法解决循环引用的问题。
    • 优点:简单直接,回收速度快
    • 缺点:需要额外的空间存放计数,无法处理循环引用的情况;
  • 标记清除法
    标记出所有不需要回收的对象,在标记完成后统一回收掉所有未被标记的对象。
    • 优点:简单直接,速度快,适合可回收对象不多的场景
    • 缺点:会造成不连续的内存空间(内存碎片),导致有大的对象创建的时候,明明内存中总内存是够的,但是空间不是连续的造成对象无法分配;
  • 复制法
    复制法将内存分为大小相同的两块,每次使用其中的一块,当这一块的内存使用完后,将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉
    • 优点:解决了内存碎片的问题,每次清除针对的都是整块内存,但是因为移动对象需要耗费时间,效率低于标记清除法;
    • 缺点:有部分内存总是利用不到,资源浪费,移动存活对象比较耗时,并且如果存活对象较多的时候,需要担保机制确保复制区有足够的空间可完成复制;
  • 标记整理
    标记过程同标记清除法,结束后将存活对象压缩至一端,然后清除边界外的内容
    • 优点:解决了内存碎片的问题,也不像标记复制法那样需要担保机制,存活对象较多的场景也使适用;
    • 缺点:性能低,因为在移动对象的时候不仅需要移动对象还要维护对象的引用地址,可能需要对内存经过几次扫描才能完成;
  • 分代式
    将对象根据存活时间的长短进行分类,存活时间小于某个值的为年轻代,存活时间大于某个值的为老年代,永远不会参与回收的对象为永久代。
    并根据分代假设(如果一个对象存活时间不长则倾向于被回收,如果一个对象已经存活很长时间则倾向于存活更长时间)对对象进行回收。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/323444.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细解读QLC SSD无效编程问题-1

此前小编关于QLC SSD有过多篇文章,具体参考如下: 为什么QLC NAND才是ZNS SSD最大的赢家? HDD与QLC SSD深度对比:功耗与存储密度的终极较量 QLC SSD在数据中心的发展前景如何? 多维度深入剖析QLC SSD硬件延迟的来源 …

肠道炎症与年龄和阿尔茨海默病病理学相关:一项人类队列研究

谷禾健康 ​阿尔茨海默 研究表明,慢性低水平的炎症(“炎症衰老”)可能是年龄相关疾病的一个介导因素,而肠道微生物通过破坏肠道屏障可能会促进炎症。 虽然老化和阿尔茨海默病(AD)与肠道微生物群组成的改变有…

Pytest fixture 及 conftest详解!

前言 fixture是在测试函数运行前后,由pytest执行的外壳函数。fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集、配置测试前系统的初始状态、为批量测试提供数据源等等。fixture是pytest的精髓所在,类似u…

力扣题:高精度运算-1.3

力扣题-1.3 [力扣刷题攻略] Re:从零开始的力扣刷题生活 力扣题1:43. 字符串相乘 解题思想:类似计算时采用的竖式乘法。首先取得num2的低位,并补齐对应的0,然后与num1进行相乘,然后进行字符串的相加操作。…

D6208双向直流马达驱动芯片 用于IPC产品,可兼容BA6208,噪声低 ,工作电源电压范围宽。

D6208 是一块单片双向马达驱动电路,它使用TTL电平的逻辑信号就能控制卡式录音机和其它电子设备中的双向马达。该电路由一个逻辑部分和一个功率输出部分组成。逻辑部分控制马达正、反转向及制动,功率输出部分根据逻辑控制能提供100mA(典型值&a…

Agilent安捷伦E4990A阻抗分析仪20Hz

Agilent安捷伦E4990A阻抗分析仪性能卓越,适用于元器件、半导体和材料测量。它具有宽广的频率范围,从20Hz到120MHz,能够适应各种不同的阻抗测量需求。在宽阻抗范围内,该仪器能够提供出色的0.045%(典型值)基本…

cesium粒子爆炸效果

效果: //添加爆炸模型window.swpecesium.addEntity.addModel({id: "model",position: {lon: 116.34516786934411,lat: 39.99753297677145,},config: {url: "./model/baozha/scene.gltf",minSize: 200,maxSize: 300,},});var scene viewer.scen…

性能优化-OpenMP概述(一)-宏观全面理解OpenMP

本文旨在从宏观角度来介绍OpenMP的原理、编程模型、以及在各个领域的应用、使用、希望读者能够从本文整体上了解OpenMP。 🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:高性能(HPC)开发基础…

MySQL-数据库概述

数据库相关概念: 数据库(DateBase)简称DB,就是一个存储数据的仓库,数据有组织的进行存储。 数据库分为关系型数据库简称RDBMS和非关系型数据库 关系型数据库简称RDBMS:建立在关系模型的基础上,由多张相互连接的二维表组成的数据库.简单来说…

民营体检@2023/24:革新、挑战与本质回归

【潮汐商业评论/原创】 被“健康焦虑”困扰的Joy决定给自己来一次全身的检查,在网上一搜才发现,不仅是体检机构,现在各大医院也都可以体检。“感觉价格也都差不多,是选公立还是体检机构呢?”Joy陷入疑惑。 随着近几年…

c++之迭代器

目录 一、迭代器 二、几种常见的迭代器类型 三、使用迭代器时注意事项 一、迭代器 在C中,迭代器是一种用于遍历容器元素的对象。迭代器提供了一种通用的方式来访问各种不同类型的容器,如数组、向量、列表、集合和映射等。 使用迭代器可以避免直接操作…