golang gc

goroutine 对比 threrad

goroutine thread
内存占用 2KB 1MB
创建销毁 用户级,go runtime负责管理 系统级
切换 3个寄存器,200ns,约2400~3600条指令时间 16个寄存器,1000~1500ns,12000~18000指令时间
  1. Go语言使用了哪种垃圾回收算法?

    • Go语言采用了三色标记清除算法,并结合写屏障技术来提高并发性。从Go 1.5开始引入了并发垃圾收集器,之后版本不断优化以减少停顿时间。
  2. 解释一下三色标记法的工作原理?

    • 三色标记法将对象分为白色、黑色和灰色三种状态:
      • 白色:表示未访问过的对象。
      • 灰色:表示已经被发现但其引用的对象还未全部检查的对象。
      • 黑色:表示已经完全扫描过且确定为存活的对象。
    • 在GC过程中,所有可达对象最终会被标记为黑色,而仅存的白色对象则被认为是垃圾并被回收。
  3. 如何触发垃圾回收?

    • Go语言的GC是自动触发的,基于分配速率和堆大小的增长情况。也可以通过调用runtime.GC()手动触发一次完整的垃圾回收过程。
  4. Go语言中的GC是并发的还是串行的?

    • Go语言的GC是并发的,这意味着它可以与应用程序代码同时运行,从而尽量减少对程序执行的影响。不过,在某些阶段仍需要短暂地暂停所有的goroutine(称为”STW”, Stop-The-World),以便安全地完成特定的操作。
  5. 什么是写屏障?为什么需要它?

    • 写屏障是在对象之间建立或更新引用时插入的一段辅助代码。它的作用是在并发GC期间确保所有活跃对象都能被正确地标记,即使这些对象正在被修改。
  6. GC Roots是什么?
    GC Roots是指那些可以直接访问到的对象集合,

    • 全局变量
    • 活跃的goroutine的栈上的所有引用
    • runtime的部分数据
  7. 堆栈上分别会有哪些数据
    栈上:

    • 不会发生逃逸的局部变量

    • 小型且大小固定的结构体、数组

    堆上:

    • make、new创建的对象
    • 大型的数据 大结构体、大数组
    • 切片 map channel,基本信息比如长度、容量、指针可能在栈上,实际的数据会在堆上
    • 逃逸的对象
  8. 什么情况会发生逃逸
    局部对象的作用域发生改变、扩散就会发生逃逸

  • 函数返回了期内局部变量的指针
  • 局部变量被全局变量持有指针
  • 局部变量的指针被传递给另外一个goroutine

golang gc
https://fatwang1.github.io/2024/09/27/2024092700/
作者
衣云乘风
发布于
2024年9月27日
许可协议