1. 系统监控
    go程序在执行时会启动一个后台线程用于系统监控。不需要依赖P,直接绑定到M上
    作用:
    1). 检查死锁:
    2). 获取下一个需要被触发的计时器。每个P都有一个最小堆结构p.timers,堆顶timer就是要触发的timer,每次调度时都会去检查已经到达时间的函数,可是如果迟迟没有发生调度,就有可能让timer执行时间发生较大偏差,因此使用监控线程来检测timer的运行,当没有timer要执行时,会进入休眠状态,当发现下一个计时器触发时间小于当前时间,会启动新的线程来触发计时器
    3). 轮询网络。非阻塞得调用netpoll检查待执行的文件描述符将处于就绪的G加入全局队列
    4). 抢占处理器。当检测到P有时间没有进行调度时,会强制进行调度
    5)决定是否需要强制垃圾回收.

  2. 触发调度的时机
    1). 线程启动
    2)G执行结束
    3)主动挂起(比如定时器,channel阻塞,等待io事件)
    使用gopark,会将当前g暂停,不会放回运行队列,_Grunning状态切换至_Gwaiting状态,触发新的调度,使用goready将G切换至_Grunnable将其加入处理器的运行队列中,等待调度器的调度
    4)监控线程检测到P长时间没有进行调度:
    (1)设置stackPreempt标志,依赖栈增长代码,对于for{}这种代码无法进行调度
    (2)实现了异步抢占,unix平台中发送sigPreempt信号,最终执行调度逻辑
    5)系统调用:
    进行系统调用时,M和G绑定在一起,让出P,P会关联到其他M,当之前的M从系统调用中恢复时,会尝试去用之前的P,如果没发用,就会去重新申请一个,如果没申请到的话,M睡眠,G放入全局队列中。

3.调度的选择
1)当全局运行队列有待执行的g时,P会有一定几率从全局队列取一部分G到本地runq中。
2)获取下一个G时,会先去本地队列中寻找,没有发现的话,会调用findrunnable取寻找直到获取到待运行的G才会返回。
3)findrunable会先看有没有gc,从本地队列获取,从全局队列获取一部分,尝试执行netpoll,恢复io事件已经就绪了的g,会被放回到全局runq中,尝试从其他Psteal一些G

4.go 内存分配
go将对象大小分为微对象(0,16B),小对象[16B, 32KB],大对象(32KB,~)。
微对象会先依次尝试微分配器,线程缓存,中心缓存和页堆,微对象会挤在一个块中,一个块中的微对象全都需要回收时才统一回收。
小对象依次尝试线程缓存,中心缓存和页堆
大对象会直接在页堆上分配内存。
mspan是内存管理的基本单位,其管理的内存不足时,会以页为单位向堆申请内存,而当用户程序向mspan申请内存时,是以对象为单位在管理。
spanclass决定了mspan单元中一个对象的大小,共有67种。
线程缓存中有67*2个mspan,初始化时不包含,需要时才去上一级组件申请,其中还有微分配器用于处理微对象。
每个中心缓存存储了一种跨度类空闲/非空闲mspan
页堆包含了67个scan的中心缓存 67个noscan的非中心缓存,堆上初始化的所有对象都由其统一管理

5.栈内存管理
目前最小的栈为2KB
编译阶段编译器会向一些函数头部插入扩充栈的函数,在执行到该函数时会去检查看栈空间是否充足。可以使用nosplit编译指令跳过栈溢出的检查不过会有溢出风险。
当需要栈空间较小时,使用全局栈缓存或者线程缓存上固定大小的空闲链表分配空间。
当栈空间较大时,使用全局的大栈缓存stackLarge获取内存空间
如果stackLarge空间不够,直接在堆上分配空间。
栈扩容时会重新申请栈,然后将旧栈中的内容拷贝到新栈中。
栈缩容是在gc时指定的,当栈内存使用不足1/4时会进行缩容,开辟新的栈空间为原来的1/2,拷贝过去。

6.cpu为了保证cache一致性 使用mesi协议,可是在操作非本地cache的数据时,需要发出invalid指令并且等待ack,很慢,于是引入了store buffer,执行写操作时先写入store buffer不用等待ack返回,但是这样会导致数据可见性问题,导致数据读取不一致,因此引入了读写屏障,store buffer有时也会因为ack回复太慢而满,所以引入了invalid queue,也会导致问题,也是用屏障解决。除此之外,程序在编译或者执行时,也有可能重排指令,为了保证数据的依赖不受破坏,也可以采用读写屏障,保证屏障前的数据读/写一定早于屏障后的数据读/写完成

最新文章

  1. jQuery的attr方法处理checkbox的问题
  2. large graph挖掘的技术基础
  3. 欢迎来怼第二周Scrum会议六(总第十三次)
  4. linux svn 重新定位SVN URL
  5. python中imread导入失败_ImportError:无法导入加载图像文件所需的Python Imaging Library(PIL)...
  6. SQL数据库高级查询命令(2)
  7. 【Codeforces Round #185 (Div. 2) C】The Closest Pair
  8. ajax 微信code获取_ajax实现微信网页授权登录
  9. Excel常用技巧大全
  10. 微信小程序统一服务消息接口
  11. nmos导通流向_讨论一下:用NMOS还是PMOS关断好? - 模拟与混合信号 - 电子工程世界-论坛 - 手机版...
  12. Mac book 合并分区,报错文件系统验证失败的解决办法
  13. 集丰照明|LED点光源安装方法
  14. 自然语言处理技术的进展和趋势
  15. JTopo添加动态连线
  16. python英译汉库模块_Python 进阶之路-翻译模块
  17. 为颜值和音质充值:南卡N2S真无线蓝牙耳机评测
  18. STM32硬件I2C的一点心得(AT24C32C和AT24C64C)
  19. 什么是VOIP和SIP?
  20. git/svn reset/revert 回滚到服务器上的某一个版本

热门文章

  1. 国际足联还不考虑在中国办一届世界杯吗?
  2. matlab中ones函数的使用方法详细介绍(附matlab代码)
  3. pgMP认证,还是再看看吧!
  4. 榛子云——短信(工具)
  5. 下载、安装安卓模拟器Genymotion
  6. ZPLII 指令参考
  7. iOS终于能微信双开了!原理竟然是这样…
  8. antd组件英文改中文
  9. linux磁盘配额分区,Linux磁盘配额
  10. 为什么美篇打不开显示服务器错误,评论为什么打不开