为什么“GC标记-清除算法”与“写时复制技术(copy-on-write)”不兼容?
在《垃圾回收算法与实现-中村成洋-2010》一书中,(以下内容来自这本书,我只是摘录了,侵删)
首先,什么是GC标记-清除算法
GC标记-清除算法:标记阶段是 把所有活动对象都做上标记的阶段。清除阶段是把那些没有标记的对象,也就是非活动对象 回收的阶段。通过这两个阶段,就可以令不能利用的内存空间重新得到利用。
其中“GC标记-清除算法”的缺点有一条是:与写时复制技术(copy-on-write)不兼容。
写时复制技术(copy-on-write)是在 Linux 等众多 UNIX 操作系统的虚拟存储中用到的高速化方法。
打个比方,在 Linux 中复制进程,也就是使用 fork() 函数时,大部分内存空间都不会被复制。只是复制进程,就复制了所有内存空间的话也太说不过去了吧。因此,写时复制技术只是装作已经复制了内存空间,实际上是将内存空间共享了。在各个进程中访问数据时,能够访问共享内存就没什么问题了。
然而,当我们对共享内存空间进行写入时,不能直接重写共享内存。因为从其他程序访问时,会发生数据不一致的情况。
在重写时,要复制自己私有空间的数据,对这个私有空间 进行重写。复制后只访问这个私有空间,不访问共享内存。
像这样,因为这门技术是“在写入时进行复制”的,所以才被称为写时复制技术。
这样的话,GC 标记 - 清除算法就会存在一个问题 : 与写时复制技术不兼容。即使没重写对象,GC 也会设置所有活动对象的标志位,这样就会频繁发生本不应该发生的复制, 压迫到内存空间。
为了处理这个问题,我们采用位图标记(bitmap marking)的方法。关于这个方法,将在 2.6 节中介绍。
我的问题是,我还是看不懂上面的解释,为什么不兼容?
“ 这样的话,GC 标记 - 清除算法就会存在一个问题 : 与写时复制技术不兼容。即使没重写对象,GC 也会设置所有活动对象的标志位,这样就会频繁发生本不应该发生的复制, 压迫到内存空间。”
怎么就 “GC 也会设置所有活动对象的标志位,这样就会频繁发生本不应该发生的复制” ?
这个我不懂。
下面的图片表示标记
在标记阶段中,程序会标记所有活动对象。