Go面试看这里了~(七)

原文地址:Go面试看这里了~(七)

1、goroutine的定义?

goroutine是与其它goroutines并行运行在同一地址空间的Go函数或方法,运行程序由一个或多个goroutine组成,与线程、进程、协程等不同,在同一用户地址空间并行独立执行functions,channels用于goroutines间的通信和同步访问控制。

2、GMP是什么?

G(goroutine):也就是协程,是用户级的轻量级线程,每个goroutine对象中的sched保存着其上下文信息。

M(machine):对内核级线程的封装,数量和CPU数一致(真正干活的对象)。

P(processor):是G和M的调度对象,用来调度G和M之间的关联关系,其数量可通过GOMAXPROCS()来设置,默认是内核数。

3、1.0前的GM调度模型?

调度器将G都分配到M,不同的G在不同的M并发运行时,都需向系统申请资源,如堆、栈、内存等,因为资源是全局的,所以会因为资源竞争而产生性能损耗,为解决这一问题,Go1.1引入P,也就是在运行时,加一个P对象,让P去管理G,M要想运行G,就需先绑定P,才能运行P管理的G。

大体可按如下几点理解:

  1. 全局互斥锁(sched.Lock)和集中存储状态。

  2. goroutine传递问题(M与M之间传递可运行的goroutine)。

  3. M做内存缓存,致使内存占用过高,数据局部性较差。

  4. 频繁syscall调用,致使严重的线程阻塞,加剧性能损耗。

4、GMP调度流程?

总结如下:

  1. 每个P有个局部队列,局部队列保存待执行的goroutine(流程2),当M绑定的P的局部队列满了之后,就会将goroutine放到全局队列(流程2-1)。

  2. 每个P绑定一个M,M是真正执行P中goroutine的实体(流程3),M从绑定的P的局部队列获取G来执行。

  3. 当M绑定的P局部队列为空时,M会从全局队列获取到本地队列来执行G(流程3.1),当从全局队列未获取到可执行G时,M会从其它P局部队列偷取G来执行(流程3.2),这种从其它P偷的方式成为work stealing。

  4. 当G因系统调用(syscall)阻塞时,会阻塞M,此时P会和M解绑,也就是handoff,并寻找新的idle的M,若无idle的M就会新建一个M(流程5.1)。

  5. 当G因channel或network产生I/O阻塞时,不会阻塞M,M会寻找其它runnable的G,当阻塞的G恢复后会重新进入runnable进入P队列等待执行(流程5.3)。

5、GMP调度过程中存在哪些阻塞?

  1. I/O,select。

  2. block on syscall。

  3. channel。

  4. 等待锁。

  5. runtime.Gosched()。

6、sysmon的作用?

sysmon也叫线程监控,用于变动的周期性检查,用处如下:

  1. 释放闲置超过5分钟的span物理内存。

  2. 如超过2分钟未垃圾回收,则强制执行。

  3. 将长时间未处理的netpoll添加到全局队列。

  4. 向长时间运行的G发起抢占调度(运行超过10ms的G,会进行retake)。

  5. 收回因syscall长时间阻塞的P。

7、三色标记原理?

先将所有对象放入白色集合中,之后进行如下操作:

  1. 从根节点遍历对象,遍历到的白色对象从白色集合中放入灰色集合。

  2. 遍历灰色集合对象,将灰色对象引用的白色集合的对象放入灰色集合中,同时将遍历过的灰色集合中的对象放入黑色集合。

  3. 循环步骤三,直到灰色对象中没有对象。

  4. 步骤四结束后,白色集合对象就是不可达对象,也就是垃圾,可进行回收。

至此,本次分享就结束了,后期会慢慢补充。

以上仅为个人观点,不一定准确,能帮到各位那是最好的。

好啦,到这里本文就结束了,喜欢的话就来个三连击吧。

以上均为个人认知,如有侵权,请联系删除。

猜你喜欢

转载自blog.csdn.net/luyaran/article/details/121414712
今日推荐