« 降低 lua gc 的开销 | 返回首页 | 关于游戏中资源管理的一些补充 »

关于 manual gc 的代码分析

今天发现 darkdestiny 朋友去年写了一个系列的 manual gc 的源码分析 :D

嗯,那段代码写的比较乱,居然真有人读完了,我真是佩服的紧啊。:D

垃圾收集的那点事(A)

这是第一篇,在那里还有 A-K,有兴趣的朋友可以自己去看。

里面提到 cache_flush 算是这个库最糟糕的一段代码了 ,好吧,我检讨,这段写的是很够戗。

代码写的乱,是我迟迟不敢把很多东西开源的主要原因 :D 。

其实一开始设计的时候,何尝不想写清楚点呢?在我自己的 svn server 上查看这个东西的修改历史,曾经也出过好几个 bug 。所以说,优化是万恶之源啊,可我们又不得不面对现实。

写的这么复杂还是因为性能缘故,希望把内存扫描次数,数据比较、内存移动、内存分配等的次数减到最少,或许以后重写一次会好一点吧。

顺便回答文章最后的一个问题:

Q: 这样这些节点不会在下一次gc_collect的时候被回收。因为弱表的children还引用着他们,维护着依赖关系,即使分配的内存已经回收了。只有用 gc_weak_next 遍历了弱表之后,这些废弃的管理节点才会从children中被删除,最终在gc_collect的时候被回收。 为啥非要主动遍历弱表才能这样呢。。。。

A: 呵呵,因为 id 得保留,不然新分配的内存块分配出来的 id 可能和弱表里记录的重复。这样从弱表里就可能取到和当初放进去不同的内存指针了。关键是在于,回收一块内存时,无法反查到内存被哪些弱表引用着。


这个东西原理其实很简单,也就是标记-清理算法。我觉得有价值开源,是因为在我们项目的实际应用中,的确得到了许多好处。有些优化策略是值得推荐的。

比如把一切事情都推迟到非做不可的时候,这样可以快速合并删除不必要的操作。标记-清理算法本质上需要维护一张内存关系图,但是,我们不必要随时生成和拓展这张图,而可以推迟到收集发生的时候。

把内存关系图和内存块在物理上隔离,也使得系统更健壮,甚至性能更高。发生收集的时候,cpu 可以工作在很小的连续内存地址空间,减少系统内存交换。也为以后升级到并行收集做准备。

另外,如果系统整个建立在 gc 的基础上的话,finalizer 的使用其实很值得推敲。一般说来 finalizer 是用于避免太细的内存粒度,和回收非内存资源用的。如果泛泛的用于类似 C++ 的析构函数的机制,会起不到应有的效果(效果指让 gc 工作的更高效)。

Comments

~

沙发!

jason说的正是,我也正在恶补一些东西。

有关GC的内容,在所有的数据结构/基础算法/OS原理书籍上都有系统详细的讲解,这些,云风估计在1995年左右,就很熟了.这类基础,属于每个敢说自己是"软件工程师"的人,都必须一清二楚的知识.

突然想起不少网页拿计算开根号的某个魔术数顶礼膜拜的事....呵呵,当然很多朋友都是拿那个来开玩笑....大家都知道,那个数的内容,在高中数学中的级数展开式中,就有出现....

"说实话云风大哥的那些代码我憋足了劲还是没什么看懂,只能看懂单个语句的意思。"

"
我去年冬季也是下苦功看过,真的没有完全看懂:)

"
.....这几位仁兄之所以看着这些内容头晕,6成是没系统学习并消化过<数据结构><OS原理>等基础知识...当然,云风没有责任从这些最基础的教起,他不是代课老师.

另,在未了解项目/内容的原理的上下文情景,就去企图阅读他人高度优化的代码--->这种事,很像美国飞机在非洲上空爆炸后,当地土著捡一起片碎片,然后,开始研究.....研究怎样做一架F22.

当然,假如这些碎片交到俄罗斯的航空研究所,那倒是可能琢磨出个七七八八来.

阿拉伯数字七是个什么东东?

我去年冬季也是下苦功看过,真的没有完全看懂:)

后来因为忙于公司的一个项目,就没有继续看下去。

程序狂:

我和你的情况一样啊。而且我还尝试了输入“阿拉伯数字七”

我也读了整整两天代码,代码乱不乱不说了,因为代码不多,主要是注释少了点,有的字段含义搞不清楚。不过使用还是很方便的。

说实话云风大哥的那些代码我憋足了劲还是没什么看懂,只能看懂单个语句的意思。

楼下就差没写“阿拉伯数字七”

我之前在云风大佬的博客上一直没有办法留言,留下不少遗憾,我一直纳闷怎么回事呢?现在才明白,原来我之前留言一直在 为了验证您是人类 那个输入框中写 七,所以留言一直无法成功,直到今天在那个对话框中写 7 之后才终于成功了。感谢上帝!

先占个位置

沙发!

Post a comment

非这个主题相关的留言请到:留言本