2009年3月1日星期日

关于垃圾回收

嗯,叫做垃圾回收还是叫做垃圾收集,这是一个问题,我在用中文搜索相关资料的时候就遇到了这个别名带来的麻烦。当然,如果叫做garbage collect就没这个问题了,可是那对检索中文资料又带来了困难。

不过事实证明,检索中文资料不是那么重要,因为几乎所有讲具体算法的书,都要付费下载...

我原本一直对垃圾回收有一定的偏见,因为它的不确定性,让我不能准确的使用内存和CPU的资源,也就是会带来那种在掌控之外的感觉,很不好。所以我比较喜欢用引用计数,但是我现在必须改变我的看法,因为引用计数的效率有点低 - 我之前居然一直没有关注到这一点,真是有些不可饶恕。

目前driver使用的值(value)和映射(mapping)的节点分别只有12、8个字节。如果为他们使用一个32位的引用计数字段,那就是4个字节,浪费了33%、50%。事实上,当然还不止这些,因为这些小内存片使用了引用、释放后,大部分情况必须作为独立分配的内存块而存在,否则释放会相当繁琐。既然是独立的内存块,那么指向他们需要一个指针,又是4个字节,管理这些小片内存,往往也需要一点资源 - 很好,一般还是4个字节(虽然有一些精巧的技术可以压缩这些空间,但是会带来很大的使用不便)。这么算下来,有效数据是12、8个字节,而额外的开销却是12个字节,浪费超过了100%。

同时,引用计数一个糟糕的情况就是,不能简单的使用内存拷贝。必须在复制指针的时候进行计数累加,在废弃指针的时候进行计数递减 - 糟糕的是这里还需要判断结果,这是一条判断跳转语句,这一切都使得执行过程显著开销增大。

对于过小的数据单元(类似上面提到的value & mapping node)采用引用计数并不是一个好主意。遗憾的是当年我并没有认真的考虑到这一点,现在真是让我捶胸顿足,后悔的很。

目前driver有一个用简单回收算法(mark-sweep)实现的回收器。但是我却不敢使用它 - 一:效率不高;二:算法是非增量的,导致系统会突然卡一下。

也许我应针对具体应用做具体的改进。

没有评论:

发表评论