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.mzph.cn/news/847397.shtml

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

相关文章

YYDS练手 130道python练习题 完整版PDF

近年来&#xff0c;Python在编程语言界里赚足了风头&#xff0c;无论是受欢迎程度&#xff0c;还是薪资待遇&#xff0c;都非常可观&#xff0c;相应的&#xff0c;Python岗位要求也越来越高&#xff0c;无论你是零基础还是老前辈&#xff0c;在Python面试中都不能轻视。 不打…

对比WPF和Avalonia的边框渲染差异

众所周知&#xff0c;诸如Border、Rectangle等元素&#xff0c;是具有边框的。但在WPF和Avalonia中&#xff0c;边框的渲染机制有所不同。 如下代码&#xff0c;Border的边框和背景色均为黑色&#xff0c;并且将透明度设为0.5&#xff1a; <Border Width"100" H…

模拟实现C++vector

一&#xff1a;C库中对于vector的介绍 vector的底层其实就是数据结构中的顺序表&#xff0c;顺序表的底层就是变长数组&#xff0c;是一段连续的物理空间 在下面的实现中&#xff0c;重点实现的是其中的迭代器和插入删除&#xff0c;下标访问等功能&#xff0c;模拟实现模板类…

Vue中使用vuex进行全局数据共享处理

1、简介 在之前的博文中&#xff0c;介绍了如何进行组件之间的数据传递&#xff0c;但是对于所有组件共享的变量来说&#xff0c;使用组件之间的数据传递实现复杂&#xff0c;因此本文引入vuex进行全局数据共享。 2、vuex的下载配置 2.1、vuex的下载 # 对于vue2来说&#xf…

IP地址开启HTTPS方法

可以使用IP地址申请SSL证书&#xff0c;申请之前必须是公网IP地址&#xff0c;不支持内网IP地址申请。 申请过程需要确定IP地址外网可以访问&#xff0c;这里特别注意只是申请过程中可以访问。访问验证过程必须采取80端口、443端口两者选择1个&#xff0c;不可以用其它端口进行…

下载视频怎么转换MP4?wmv转换mp4,推荐这3种方法

在数字化时代&#xff0c;我们经常需要从网上下载各种视频&#xff0c;但有时候下载的视频并不是我们想要的格式&#xff0c;比如WMV。为了能在更多的设备上播放或进行编辑&#xff0c;我们可能需要将其转换为更通用的MP4格式。 那么&#xff0c;下载的视频如何转换成MP4呢&am…

第三篇 编译器和译码器

实验三 编码器和译码器 3.1 实验目的 上一章节我们学习了简单组合逻辑电路——多路数据选择器&#xff0c;在本章节我们将学习另外一种数字系统中常见的简单组合逻辑电路——编码器和译码器。然后通过一个设计一个简易的计算器让大家进一步巩固FPGA开发的流程和方法。 本节您…

“神经网络之父”和“深度学习鼻祖”Geoffrey Hinton

“神经网络之父”和“深度学习鼻祖”Geoffrey Hinton在神经网络领域数十年如一日的研究&#xff0c;对深度学习的推动和贡献显著。 一、早期贡献与突破 反向传播算法的引入&#xff1a;Hinton是将反向传播&#xff08;Backpropagation&#xff09;算法引入多层神经网络训练的…

【C++进阶】深入STL之vector:构建高效C++程序的基石

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;模拟实现string &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀STL之vector &#x1f4d2;1.ve…

网络编程(七)

网络编程&#xff08;七&#xff09; UNIX域套接字&#xff08;本地间进程间通信的技术&#xff09;&#xff08;S文件&#xff09;基于TCP传输基于UDP传输 UNIX域套接字&#xff08;本地间进程间通信的技术&#xff09;&#xff08;S文件&#xff09; socket同样也可以用于本…

OpenCV-绘制虚线

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 功能函数 // 绘制虚线 void DrawDottedLine(cv::Mat &input, cv::Point p1, cv::Point p2, cv::Scalar color, int thickne…

Android Graphics 显示系统 - Android Jank detection with FrameTimeline

“ 最近有公司同事在处理UI卡顿及FPS自动化监测的问题&#xff0c;我也顺便看了一点相关的内容&#xff0c;其中在Perfetto的官方说明文档中有一篇关于利用FrameTimeLine进行Jank监测的解读&#xff0c;个人觉得蛮有意思的&#xff0c;借助工具翻译该篇文章并加上本人拙劣的解读…

C++系列-类模板

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类模板的定义格式&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; template<class T> class Stack { public:Stack(size_…

【Java EE】网络原理——HTTPS

目录 1.HTTPS是什么 2.“加密”是什么 3.HTTPS的工作过程 3.1引入对称加密 3.2 引入非对称加密 4.中间人攻击 5.引入证书 6. 理解数据签名 7.通过证书解决中间人攻击 7.1 查看浏览器的授信任证书发布机构 7.2 中间人有没有可能篡改证书&#xff1f; 7.3 中间人整个掉…

latex公式输入练习

给大家提供几个公式供大家练习latex输入数学公式&#xff0c;同时也是对自己新学latex语言的一种复习吧。&#xff08;如果大家对latex输入公式感兴趣&#xff0c;推荐一下哔站视频&#xff1a;LaTeX公式保姆级教程 (以及其中的各种细节)_哔哩哔哩_bilibili&#xff09; 公式一…

基于.NetCore和ABP.VNext的项目实战七:全局异常处理并日志记录

ABP框架已经默认为我们实现了全局的异常模块,这里我们自定义全局异常模块,先在HelloWorldController中写一个异常接口,测试下ABP的默认全局异常: [HttpGet][Route("Exception")]public string Exception(){throw new NotImplementedException("这是一个未实…

Vue——监听器简单使用与注意事项

文章目录 前言编写简单demo注意事项 前言 监听器&#xff0c;在官网中称为侦听器&#xff0c;个人还是喜欢称之为监听器。官方文档如下&#xff1a; vue 官网 侦听器 编写简单demo 侦听器在项目中通常用于监听某个属性变量值的变化&#xff0c;并根据该变化做出一些处理操作。…

leetcode第263题:丑数

丑数的因子只能是2,3,5。但是可能有多个2&#xff0c;多个3&#xff0c;多个5.因此需要循环地除以2、3、5. public class Solution {public bool IsUgly(int n) {if (n < 0) {return false;}int[] factors {2, 3, 5};for ( int i0;i<3;i) {int factorfactors[i];while …

Visual C++2010学习版详细安装教程(超详细图文)

Visual C 介绍 Visual C&#xff08;简称VC&#xff09;是微软公司推出的一种集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于开发C和C语言的应用程序。它提供了强大的编辑器、编译器、调试器、库和框架支持&#xff0c;以及丰富的工具和选项&#xff0c;使得开…

【计算机-ARM】

计算机-ARM ■ 指令集■ 1. RISC■ 2. CISC ■ ARM简介■ 1.■ 2. ■ ARM-CPU体系架构■ 1. M0■ 2. M3■ 3. M4■ 4. M7■ 5. M7■ 6. M7 ■ ARM-寄存器■ 1. 通用寄存器■ 2.■ 3.■ 4. ■ ARM-工作模式■ ARM-寄存器组■ ARM-异常向量表■ 由于soc0x00000000 是存放IROM芯片…