版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010853261/article/details/84104022
本文主要描述Golang底层的一些原理与机制,包括4个主题
1)Golang的memory manager and allocation
2)Golang的goroutine scheduler原理
3)Golang的channel实现goroutine concurrent原理
4)Golang的garbage collection原理
这篇博客只是一个绪论,只是简单总结一下以上各个主题的主要内容。由于题主以前写过两年的Java,所以希望在学习golang底层原理之后能够将两者相关的机制对比起来。
1. Golang的memory manager and allocation
- tcmalloc是怎么做内存管理的,golang的memory manager是基于tcmalloc的。
- 逃逸分析
- 对象保存位置 heap or stack
- golang的多级内存分配是怎么做的?有哪几级?分别对应什么模型?什么情况下会逐级网上申请?mcache、mcentral、mheap。
- goroutine的stack是从哪里申请到的
2. Golang的goroutine scheduler原理
- 调度的goroutine和底层的OS线程有什么关系
- M、G、P分别代表什么,维护了哪些数据,G、M、P的映射关系是怎么样的
- 如果goroutine-A因为syscall或则DB的IO等操作blocking了,scheduler会怎么做?因为底层的OS线程也会阻塞,所以需要探讨会怎么做;如果goroutine-A的blocking恢复了,会继续在原来的M和P中运行嘛?
- Go的系统里面的P和M的数量上限是多少?scheduler是怎么动态调度的。
- 如果某一个P里面goroutine的runqueue执行完毕,work-stealing是怎么做的
GOMAXPROCS数量等价于P数量
new goroutine 等价于G,等价于 runtime·newproc()
newm()创建内核线程等价于M
上面的这些机制不仅仅理解原理还要对照源码做分析
-
如果一个goroutine一直占有CPU又不会有阻塞或则主动让出CPU的调度,scheduler怎么做抢占式调度让出CPU‘
-
G、P、M状态机
go1.2版本之前的调度器存在的问题
3. Golang的channel实现goroutine concurrent原理
本文假设读者已经了解Go里面channel的基本使用方式。本文主要讲解以下几个问题:
- 什么是CSP,channel是怎么基于CSP这种思想设计的
- channel的基本使用方式
- make channel的调用,底层执行了什么什么操作
- channel底层的存储结构是怎么样的
- 向channel里面发送或则从channel接收数据的流程是怎么样的,与底层存储有什么关系
- 对于一个有缓冲的channel,如果channel满了,goroutine-A继续写入会发生什么?
- 对于一个有缓冲的channel,如果channel为空,goroutine-B从里面读会发生什么?
- 对于一个有缓冲的channel,当channel未满且非空时候,读写会发生什么?
- 对于6、7、8主要关注goroutine和调度器做出的与channel相关的决策。
- 在不同时机(case6、7、8)下如果close一个channel会有什么后果,如果继续进行读写会造成什么后果。
- 如果channel是nil,往里面读写会产生什么后果
- channel实现底层有哪些性能优化的地方:优化锁和内存copy?
分析的主要源码部分:chan.go、runtime2.go、malloc.go、proc.go、mbarrier.go等等
主要涉及的其余源码文件的函数有:
1)mallocgc()、memmove()
2)gopark()、goready()
3)lock()、unlock()
4)getg()、acquireSudog()、releaseSudog()
4. Golang的garbage collection原理
- GC回收算法有哪些,有没有针对不同性质(老年代和新生代)做不同算法处理
- GC的起点是那些,检测GC的算法是什么