垃圾回收 相比程序员直接 free 和 delete 之类的,有什么优化(内存碎片)

参考解析

题目来源:字节跳动

答案:

goalng1.8的GC采用三色标记法+混合写屏障

三色标记法:将所有对象分为三类,白色、黑色与灰色。

白色:暂无对象引用的潜在垃圾,其内存可能会被垃圾回收器回收

黑色:表示活跃的对象

灰色:黑色与白色的中间状态

三色标记算法分五步进行。

  1. 将所有的对象标记为白色
  2. 从根节点出发,将第一次遍历到的节点标记为灰色
  3. 遍历节点,将灰色节点遍历到的白色节点标记为灰色,把遍历到的灰色节点标记为黑色
  4. 循环执行该过程
  5. 直到没有灰色节点,回收所有白色节点

屏障机制分为插入屏障和删除屏障,插入屏障实现的是强三色不变式,删除屏障则实现了弱三色不变式。值得注意的是为了保证栈的运行效率,屏障只对堆上的内存对象启用,栈上的内存会在GC结束后启用STW重新扫描。

插入屏障:对象被引用时触发的机制,当白色对象被黑色对象引用时,白色对象被标记为灰色(栈上对象无插入屏障)。

C语言这种较为传统的语言通过mallocfree手动向操作系统申请和释放内存,这种自由管理内存的方式给予程序员极大的自由度,但是也相应地提高了对程序员的要求。C语言的内存分配和回收方式主要包括三种:

  • 函数体内的局部变量:在栈上创建,函数作用域结束后自动释放内存
  • 静态变量:在静态存储区域上分配内存,整个程序运行结束后释放(全局生命周期)
  • 动态分配内存的变量:在堆上分配,通过malloc申请,free释放

CC++Rust等较早的语言采用的是手动垃圾回收,需要程序员通过向操作系统申请和释放内存来手动管理内存,程序员极容易忘记释放自己申请的内存,对于一个长期运行的程序往往是一个致命的缺点。