垃圾回收 相比程序员直接 free 和 delete 之类的,有什么优化(内存碎片)
参考解析
题目来源:字节跳动
答案:
goalng1.8的GC采用三色标记法+混合写屏障
三色标记法:将所有对象分为三类,白色、黑色与灰色。
白色:暂无对象引用的潜在垃圾,其内存可能会被垃圾回收器回收
黑色:表示活跃的对象
灰色:黑色与白色的中间状态
三色标记算法分五步进行。
- 将所有的对象标记为白色
- 从根节点出发,将第一次遍历到的节点标记为灰色
- 遍历节点,将灰色节点遍历到的白色节点标记为灰色,把遍历到的灰色节点标记为黑色
- 循环执行该过程
- 直到没有灰色节点,回收所有白色节点
屏障机制分为插入屏障和删除屏障,插入屏障实现的是强三色不变式,删除屏障则实现了弱三色不变式。值得注意的是为了保证栈的运行效率,屏障只对堆上的内存对象启用,栈上的内存会在GC结束后启用STW重新扫描。
插入屏障:对象被引用时触发的机制,当白色对象被黑色对象引用时,白色对象被标记为灰色(栈上对象无插入屏障)。
C
语言这种较为传统的语言通过malloc
和free
手动向操作系统申请和释放内存,这种自由管理内存的方式给予程序员极大的自由度,但是也相应地提高了对程序员的要求。C
语言的内存分配和回收方式主要包括三种:
- 函数体内的局部变量:在栈上创建,函数作用域结束后自动释放内存
- 静态变量:在静态存储区域上分配内存,整个程序运行结束后释放(全局生命周期)
- 动态分配内存的变量:在堆上分配,通过
malloc
申请,free
释放
C
、C++
和Rust
等较早的语言采用的是手动垃圾回收,需要程序员通过向操作系统申请和释放内存来手动管理内存,程序员极容易忘记释放自己申请的内存,对于一个长期运行的程序往往是一个致命的缺点。