Go语言垃圾回收(GC原理)

1. GC回收机制

1.1 V1.3标记清除法

(1)概述

1.STW暂停

STW(暂停业务逻辑,找出可达和不可达对象)

2.对可达对象做上标记

标记完成之后,对象5和对象6不可达,被GC清除.之后STW结束.

(2).缺点
  • STW :让程序暂停,程序出现卡顿.
  • 标记需要扫描整个heap.
  • 清除数据会产生heap碎片.

1.2 V1.5三色标记法

(1) 概述

1.程序创建起初,全部标记为白色,将所有对象放入白色集合中.

2. 将程序的根节点集合展开,遍历Root Set(非递归形式,只遍历一次).得到灰色节点

3.遍历灰色标记表,将可达的对象从白色标记为灰色,遍历之后的灰色,标记为黑色.

4.循环执行第三步,直到灰色标记标中无任何对象.

5.收集所有白色对象(垃圾)

(2) 缺点

如果三色标记法不被STW保护.

当一个白色对象被黑色对象所引用,且灰色对象与它之间的可达关系的白色对象遭到破坏,就会出现对象丢失的情况.

避免上述情况最简单的方式就是STW.

尽量减少STW对程序性能的损耗

  • 强三色不变式: 强制行的不允许黑色对象引用白色对象.
  • 弱三色不变式: 黑色可以引用白色对象,白色对象存在其它灰色对象对它的引用,或者可达它的链路上游存在灰色对象.

屏障机制实现强弱三色不变式

  • 插入屏障: 在A对象引用B对象的时候,B对象被标记为灰色.(将B挂在A下游,B必须被标记为灰色) 满足强三色不变式(不存在黑色对象引用白色对象的情况了,因为白色会强制变成灰色) 插入屏障不在栈上使用.
添加一个下游对象(当前下游对象slot,新下游对象ptr) {//1标记灰色(新下游对象ptr)//2当前下游对象slot=新下游对象ptr
}

插入屏障流程:

由于并发特性,此刻外界向对象4添加添加对象8,对象1添加对象9.对象4在堆区,即将触发插入屏障机制.

当灰色标记表中为空,准备回收白色标记之前,重新遍历扫描一次栈空间.此时加STW暂停保护栈,防止外界干扰.(这也是插入写屏障的不足,结束时需要STW重新扫描栈,10~100ms).

  • 删除屏障: 被删除的对象,如果自身为灰色或者白色,那么被标记为灰色. 满足弱三色不变式(保护灰色对象到白色对象的路径不会断)
添加下游对象(当前下游对象slot , 新下游对象ptr) {//1if 当前下游对象slot是灰色 || 白色{标记灰色(当前下游对象slot)}//2当前下游对象slot = 新下游对象ptr
}

删除屏障流程:

灰色对象1删除对象5,如果不触发删除写屏障,5-2-3路径与主链路断开,最后均会被当作垃圾清除.

删除写屏障回收精度低,一个对象即使被删除了最后一个指向它的指针,也依旧可以活过这一轮,在下一轮的GC中被清理掉.

1.3 V1.8混合写屏障机制

(1) 概述

具体操作:

  1. GC开始将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW)
  2. GC期间,任何在栈上创建的新对象,均为黑色.
  3. 被删除的对象标记为灰色.
  4. 被添加的对象标记为灰色.

混合写屏障流程:

1.GG刚开始,默认都为白色.

2.三色标记法,优先扫描全部栈对象,将可达对象均标记为黑.

2. GPM调度模型设计

2.1. GPM

  1. G(goroutine协程):Go协程
  2. P(Processor处理器):包含运行Go代码的必要资源,也有调度go协程的能力
  3. M(machine线程):工作线程,由操作系统调度

P的本地队列存放的是等待运行的G,数量不能超过256G,优先将新创建的G放在P的本地队列中,如果满了会放在全局队列中.

GOMAXPROCS:是在程序启动时创建的,指定P的个数.可以通过环境变量,或者在程序中通过runtime.GOMAXPROCS()来设置.(允许相应个数的go协程在同一时刻并行执行)

Go语言本身限制M的最大量为10000.一般M的个数会略大于P.

2.2. 调度器设计策略

  1. 复用线程:避免频繁的创建,销毁线程.而是对线程复用.
    1. work stealing机制: 当本线程无可运行的G时,尝试从其他线程绑定的P偷取G,而不是销毁线程.
    2. hand off机制: 当本线程因为G进行调用阻塞时,线程将释放绑定的P,将P转移给其他空闲线程执行.
  1. 利用并行: GOMAXPROCS设置P的数量,最多由GOMAXPROCS个线程分布在多个CPU上同时运行.
  2. 抢占:在Go中,一个goroutine最多占用CPU10ms , 防止其他goroutine长期得不到执行.
  3. 全局G队列:当M执行work stealing从其他P中偷不到G时,它可以从全局G队列获取G.

2.3. go func()

  1. 有两个存储G的队列,一个是局部调度器P的本地队列,一个全局队列.新创建的G会先保存在P的本地队列中,如果P的本地队列中已满就会保存在全局的队列中.
  2. G只能运行在M中,一个M必须持有一个P.M会从P的本地队列弹出一个可执行状态的G来执行,如果P的本地队列为空,偷取其他队列的P来执行 .
  3. 一个M调度G执行的过程是一个循环机制.
  4. 当M执行某一个G时候如果发生了syscall或其余阻塞操作,M会阻塞,如果当前有一些G在执行,runtime会把这个线程M从P中摘除,然后再创建一个新的操作系统的线程(如果有空闲的线程可用就复用空闲线程)来服务这个P.
  5. 当M系统调用结束后,这个G会尝试获取一个空闲的P执行;并放入到这个P的本地队列.如果获取不到P,那么这个线程M变成休眠状态,加入到空闲线程中,然后这个G会被放入全局队列中.

2.4. 调度器的生命周期

M0:启动程序后的编号为0的主线程.在全局变量runtime.m0中,不需要再heap上分配.负责执行初始化操作和启动第一个G.启动第一个G之后,M0就和其他M一样了.

G0:每次启动一个M,第一个创建的gourtine,仅用于负责调度的G,不指向任何可执行的函数.在调度或系统调用时,会使用M切换到G0来调度.

2.5. 补充

自旋线程会不断的寻找G(优先寻找全局队列中的G)

从全局队列到P本地队列的负载均衡:从全局队列取的个数: n = min(len(GQ) / GOMAXPROCS + 1 , len(GQ)/2)

GQ:全局队列的总长度

偷取另一个P本地队列中的G: 将要偷取的P中的本地队列一分为二,偷取后一半的G.

自旋线程的最大限制: 自旋线程+执行线程 <= GOMAXPROCS

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

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

相关文章

【 0 基础 Docker 极速入门】镜像、容器、常用命令总结

Docker Images&#xff08;镜像&#xff09;生命周期 Docker 是一个用于创建、部署和运行应用容器的平台。为了更好地理解 Docker 的生命周期&#xff0c;以下是相关概念的介绍&#xff0c;并说明它们如何相互关联&#xff1a; Docker&#xff1a; Docker 是一个开源平台&#…

JAVA基础|File,IO流

File类只能对文件本身进行操作&#xff0c;不能读写文件里面存储的数据 IO流就是对文件进行读写的 一. File类 &#xff08;一&#xff09;创建对象 import java.io.File;public class FileTest1 {public static void main(String[] args) {// 1. 创建一个File对象&#xff…

Parallels Desktop for Mac 19.4.0更新了哪些内容?有什么改进?

带来了重新设计的共享 Mac 文件夹版本&#xff0c;这些文件夹现在是符号链接&#xff0c;像指针一样指向您的 Mac 文件夹中的文件&#xff0c;同时仍然显示在 Windows 的本地磁盘上。 修复了由于共享文件夹问题导致 NinjaTrader 无法正常启动的问题。 修复了由于共享文件夹问…

Linux VSCode和Debug相关的备忘

在使用Linux时&#xff0c;总是会遇到一些意想不到的困难。而且似乎无穷无尽。这里打算写一个笔记&#xff0c;以后逐步来完善。特别是&#xff1a;调试的技能&#xff0c;总是占程序员的主要部分。在设置可视化调试环境过程中&#xff0c;常会同样陷入困境&#xff0c;有时深感…

小猪APP分发:如何轻松进行在线封装APP

你是否曾经因为需要封装一个新版本的APP而感到头疼&#xff1f;传统的封装过程往往繁琐且耗时。但是&#xff0c;别担心&#xff0c;现在有了“小猪APP分发”&#xff0c;一切变得如此简单。 小猪APP分发www.appzhu.net是一个专门提供在线APP封装服务的平台。无论你是开发者还…

Assignement5: Multi-threaded Producer Consumer Pipeline

Assignement5: Multi-threaded Producer Consumer Pipeline. 一起来打卡学习&#xff01;

NetApp 面向医疗保健行业的解决方案

NetApp 面向医疗保健行业的解决方案 旨在为您提供令人惊叹的临床应用程序性能&#xff0c;并通过内置的安全性和监控功能&#xff0c;由无中断的运营连续性提供支持。 为护理而设计 对于专注于整个医疗保健产业链&#xff08;包括提供商、付款方、生命科学&#xff09;的创新能…

跟着AI学AI_02, 时域频域和MFCC

AI&#xff1a;ChatGPT4o 时域和频域是信号处理中的两个基本概念&#xff0c;用于描述信号的不同特性。 时域 时域&#xff08;Time Domain&#xff09; 是对信号随时间变化的描述。在时域中&#xff0c;信号是作为时间的函数来表示的。 时域表示&#xff1a;例如&#xff0…

【热点】老黄粉碎摩尔定律被,量产Blackwell解决ChatGPT耗电难题

6月3日&#xff0c;老黄又高调向全世界秀了一把&#xff1a;已经量产的Blackwell&#xff0c;8年内将把1.8万亿参数GPT-4的训练能耗狂砍到1/350&#xff1b; 英伟达惊人的产品迭代&#xff0c;直接原地冲破摩尔定律&#xff1b;Blackwell的后三代路线图&#xff0c;也一口气被…

【康耐视国产案例】智能AI相机联合OSARO为Zenni眼镜实现订单履约自动化

在电商潮流下&#xff0c;Zenni眼镜作为全球领先的在线眼镜零售商&#xff0c;每年销售超过600万副眼镜&#xff0c;却面临着一个独特而复杂的问题——需要通过扫描眼镜盒内的条形码来处理订单。传统手动处理已经到达流程瓶颈&#xff0c;急需一种更加自动化、可扩展的方法。为…

Pikachu靶场下载、配置

目录 下载 配置 新版小蓝皮 搭建网站 搭建数据库 初始化靶场 旧版小绿皮 配置数据库 配置网站 下载 GitHub下载地址&#xff1a; 百度网盘&#xff1a;https://pan.baidu.com/s/1j2WpdLvwAbmpAH76d_yitw?pwdwf8j 提取码&#xff1a;wf8j 迅雷链接&#xff1a;http…

【STL深入浅出】之从零到精通:vector使用与模拟

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

thinkphp6 queue队列的maxTries自定义

前景需求&#xff1a;在我们用队列的时候发现maxtries的个数时255次&#xff0c;这个太影响其他队列任务 我目前使用的thinkphp版本是6.1 第一部定义一个新的类 CustomDataBase&#xff08;我用的mysql数据库存放的队列&#xff09; 重写__make 和createPlainPayload方法 …

每日两题 / 34. 在排序数组中查找元素的第一个和最后一个位置 33. 搜索旋转排序数组(LeetCode热题100)

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣&#xff08;LeetCode&#xff09; 根据二分函数&#xff0c;得到>target和<target的两个&#xff0c;分别是答案的l和r class Solution { public:vector<int> searchRange(vector<int>& nums,…

【Uniapp小程序】自定义导航栏uni-nav-bar滚动渐变色

效果图 新建activityScrollTop.js作为mixins export default {data() {return {navBgColor: "rgba(0,0,0,0)", // 初始背景颜色为完全透明navTextColor: "rgba(0,0,0,1)", // 初始文字颜色};},onPageScroll(e) {// 设置背景const newAlpha Math.min((e.s…

小学数学出题器-Word插件-大珩助手

Word大珩助手是一款功能丰富的Office Word插件&#xff0c;旨在提高用户在处理文档时的效率。它具有多种实用的功能&#xff0c;能够帮助用户轻松修改、优化和管理Word文件&#xff0c;从而打造出专业而精美的文档。 【新功能】小学数学出题器 1、实现了难度设定&#xff1b;…

HCIP-Datacom-ARST自选题库__MAC【14道题】

一、单选题 1.缺省情况下&#xff0c;以下哪种安全MAC地址类型在设备重启后表项会丢失? 黑洞MAC地址 Sticky MAC地址 安全动态MAC地址 安全静态MAC地址 2.华为交换机MAC地址表中的动态sticky MAC地址的默认老化时间是多少秒? 300 不会老化 400 500 3.华为交换机MA…

Golang | Leetcode Golang题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; type pair struct {node *TreeNodenum int }func sumNumbers(root *TreeNode) (sum int) {if root nil {return}queue : []pair{{root, root.Val}}for len(queue) > 0 {p : queue[0]queue queue[1:]left, right, num : p.node.Left, …

大规模 Transformer 模型 8 比特矩阵乘

本文基于 Hugging Face Transformers、Accelerate 以及 bitsandbytes库。 Transformers&#xff1a;Hugging Face 提供的一个开源库&#xff0c;包含了多种预训练的 Transformer 模型&#xff0c;方便用户进行各种 NLP 任务。Accelerate&#xff1a;Hugging Face 开发的一个库…

大型语言模型的工作原理(LLM:从零学起)

目录 一、说明 二、LLM如何运作 三、预训练&#xff1a;基本模型 四、微调&#xff1a;培训助手 五、RLHF&#xff1a;从人类反馈中强化学习 六、提示工程 七、总结 一、说明 这是我们谈论LLM系列的第二篇文章。在本文中&#xff0c;我们旨在为大型语言模型 &#xff08;LLM&am…