GO语言学习笔记

导图:GO语言四大模块

 

1.调度器

  GMP调度算法:

 

 

阻塞补充:

在 Go 里面阻塞主要分为以下 4 种场景:
  1. 由于原子、互斥量或通道操作调用导致 Goroutine 阻塞,调度器将把当前阻塞的 Goroutine 切换出去,重新调度 LRQ 上的其他 Goroutine; 只阻塞当前G
  2. 由于网络请求和 IO 操作导致 Goroutine 阻塞。Go 程序提供了网络轮询器(NetPoller)来处理网络请求和 IO 操作的问题,其后台通过 kqueue(MacOS),epoll(Linux)或 iocp(Windows)来实现 IO 多路复用。通过使用 NetPoller 进行网络系统调用网络轮询器使用系统线程 阻塞的G交给netpoller
  3. 当调用一些系统方法的时候(如文件 I/O),如果系统方法调用的时候发生阻塞,这种情况下,网络轮询器(NetPoller)无法使用,而进行系统调用的 G1 将阻塞当前 M1。调度器引入 其它M 来服务 M1 的P。 阻塞M
  4. 如果在 Goroutine 去执行一个 sleep 操作,导致 M 被阻塞了。Go 程序后台有一个监控线程 sysmon,它监控那些长时间运行的 G 任务然后设置可以强占的标识符,别的 Goroutine 就可以抢先进来执行。阻塞M但是可以被抢占

2.netpoll

  Go 程序提供了网络轮询器(NetPoller)来处理网络请求和 IO 操作的问题,其后台通过 kqueue(MacOS),epoll(Linux)或 iocp(Windows)来实现 IO 多路复用。通过使用 NetPoller 进行网络系统调用网络轮询器使用系统线程 将阻塞的G交给netpoller

3.内存管理

  概述:

·Go 在程序启动时,会向操作系统申请一大块内存,之后自行管理。
·Go内存管理的基本单元是mspan,它由若干个页组成,每种mspan可以分配特定大小的 object。
·mcache,mcentral, mheap是Go内存管理的三大组件,层层递进。mcache 管理线程在本地缓存的mspan;mcentral管理全局的 mspan 供所有线程使用;mheap 管理 Go 的所有动态分配内存。
·极小对象会分配在一个object 中,以节省资源,使用 tiny 分配器分配内存;一般小对象通过 mspan 分配内存;大对象则直接由 mheap 分配内存。

后记:

Golang 运行时的内存分配算法主要源自 Google 为 C 语言开发的
TCMalloc 算法,全称Thread-Caching Malloc。核心思想就是把内存分为多级管理,从而降低锁的粒度。它将可用的堆内存采用二级分配的方式进行管理:每个线程都会自行维护一个独立的内存池,进行内存分配时优先从该内存池中分配,当内存池不足时才会向全局内存池申请,以避免不同线程对全局内存池的频繁竞争。

4.GC 

垃圾回收算法有很多,主要有:引用计数、标记-清除、分代收集

口述,go gc 的原理 三色标记发+混合写屏障 思路 尽量减少stw的时间,

1.只在开始标记阶段和标记结束阶段使用stw,
2.标记阶段采用写屏障,将新建和修改的放入单独的marking队列。
3.标记结束阶段再次扫描marking队列,关闭写屏障
 

什么是内存屏障?

垃圾收集中的屏障技术更像是一个钩子方法,它是在用户程序读取对象、创建新对象以及更新对象指针时执行的一段代码,根据操作类型的不同,我们可以将它们分成读屏障(Read barrier)和写屏障(Write barrier)两种,因为读屏障需要在读操作中加入代码片段,对用户程序的性能影响很大,所以编程语言往往都会采用写屏障保证三色不变性。写屏障是当对象之间的指针发生改变时调用的代码片段。

 

posted on 2024-05-08 10:33  zyz913614263  阅读(9)  评论(0编辑  收藏  举报

导航