GO语言学习笔记
导图:GO语言四大模块
1.调度器
GMP调度算法:
阻塞补充:
在 Go 里面阻塞主要分为以下 4 种场景:
- 由于原子、互斥量或通道操作调用导致 Goroutine 阻塞,调度器将把当前阻塞的 Goroutine 切换出去,重新调度 LRQ 上的其他 Goroutine; 只阻塞当前G
- 由于网络请求和 IO 操作导致 Goroutine 阻塞。Go 程序提供了网络轮询器(NetPoller)来处理网络请求和 IO 操作的问题,其后台通过 kqueue(MacOS),epoll(Linux)或 iocp(Windows)来实现 IO 多路复用。通过使用 NetPoller 进行网络系统调用网络轮询器使用系统线程 阻塞的G交给netpoller
- 当调用一些系统方法的时候(如文件 I/O),如果系统方法调用的时候发生阻塞,这种情况下,网络轮询器(NetPoller)无法使用,而进行系统调用的 G1 将阻塞当前 M1。调度器引入 其它M 来服务 M1 的P。 阻塞M
- 如果在 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) 编辑 收藏 举报