« 模型顶点数据的压缩 | 返回首页 | 十年圆梦 »

C++ 0x 中的垃圾收集

g9 老大的 blog 里最近写了篇 关于C++ 0x 里垃圾收集器的讲座 。这是我看见的第一篇关于 C++ 0x 标准中GC 的中文文章。

最近两年我对 gc 很感兴趣 :D 已经在项目中用了两年。项目从 C++ 转到 C ,gc 模块的实现发生了变化,但是本质却没有变。我对 C++ 加入 gc 是非常欢迎的,这点在以前写的另一篇 blog 中已经表明过态度。

记得两年前,当有机会当面问 Bjarne Stroustrup 关于 C++ 发展的问题时,我毫不犹豫的讲出自己对 gc 的迫切期待,并希望能够以最小代价的把 gc 加入 C++ 。因为已经实现过一些 C++ 的 gc 模块,我有一些语言上的需求。当时描述了自己的想法,可惜英文实在是太差了,完全说不清楚 :( 因为没听明白我的意思,Bjarne Stroustrup 他老人家似乎也很无奈,最后只是建议中国的程序员应该参于到语言的标准化事务当中去,一直以来,C++ 标准委员会中似乎没有来至中国大陆的程序员。

既然 C++ 是你的工具,你就应该努力把自己对工具的改进需求说出来。

其实我的需求很简单,就是 C++ 中应该加入一些对数据结构中数据类型的有限描述。其实只做内存管理的话,类型信息只需要区分数据还是指针就够了。具体数据类型可以忽略。

我的想法就是像虚表一样,给每个类多加一张表,描述这个对象中指针的位置(记录一个偏移量)。由于 C++ 的对象布局比较复杂,这个工作如果不在编译器里做,会相当麻烦。有这样的信息,gc 就可以容易的遍历内存了。看那篇文章的介绍,C++ 的 gc 似乎用 gc_strict gc_relax 这样的关键字来描述一整块内存区内有没有指针,而没有更细致的精确到每个数据上。这跟已有的 C 的 gc 库 实现类似。我猜测这些是为了兼容 POD 类型设计的,对于 C++ 自己的类,应该可以更好的解决。毕竟编译器知道全部的类型信息。

除此之外,遍历堆栈依旧是个问题,但已经好多了。遍历可以用各种语法糖来实现,反正 C++ 有了 template 后,什么诡异的写法都弄的出来 ;-p

最后说两句 gc 的效率问题。gc 没有人肉内存管理效率高是一种普遍的误解。如果不是靠臆测,而是自己实现一个 gc 模块,然后做代码剖析的话,很容易相信 gc 可以带来更高的性能。关于 gc 和人肉内存管理之间的性能话题,以前写过太多,吵的太多,嚼着都没味道了。今天就不再写了。

Comments

时至今日,看到15的楼评论依然觉得很傻比

gc 不能帮助回收系统资源?
gc的回收在另一个线程内。所以即使能,考虑到大量系统资源只能在创建线程内回收,所以给予多线程的回收也起不到相应的作用。也许你可以利用事件机制通知回收,但这样的话线程之间的关联性增加导致的性能下降会很明显的。

有没有这样一个GC的实现:
调用方式为:
A* a = new (GC) A();

这里的a可以被自动回收,并且自动执行


a->~A()

怎么没听说在C中增加GC的需求。

C++本身的模块化就没做好,比如我开发一个中型工程,单机游戏,我不想使用一些复杂的C++功能,可能给我带来bug什么的,可是你就不能选择去除复杂模块的C++,当然不是指去除一些头文件,实际上,我连类的继承什么的都非常讨厌,我最早是C程序员,我刚开始用C++时,以为就自己这样,后来发现c和C++的争论....
C只要再加入一些包装的功能,或者把C++本身的功能模块化,为什么这么简单的方法那些大牛都不用,其实有时一线的工人比工程师更能解决实际问题.

对C++了解得越多,就越是对使用C++感到心惊胆战!

心口中弹!看了《新黑客字典》和《UNIX编程艺术》才知道为什么CPP会如此的复杂,以前一个开源社区的家伙一直讲CPP是世界上最难的语言,比汇编还难,的确~汇编只是烦琐但并不算复杂,但CPP是复杂+烦琐~还是像C和Scheme这样的比较爽!

对C++了解得越多,就越是对使用C++感到心惊胆战!

gc很有用,但不是必须的。

一个好的GC,应该是可以满足根据不同的需要变换内存管理策略的,比如像服务器程序,因为长期运行的稳定性要求很高,所以在速度和内存碎片的整理之间应该偏向后者,而一般的应用应该在两者之间取得一个均衡,对于非常重视效率的程序则应该偏向前者。这是我的看法:)

生活中没有除了工作,睡觉,
也该有点其它的东西.

C++ 是否过度设计,不好说.
C++ 是否被过度使用了,肯定的.

太同意Atry了。
对C++了解得越多,就越是对使用C++感到心惊胆战。

2年前?是不是Bjarne Stroustrup来华时一起吃的饭?

刚看完《C++语言的设计和演化》,再一次感觉到C++太复杂了,它不应该是一种语言,而应该分成很多种语言。GC是C++所剩无几的可能加入还没有加入的功能特性了。我赞同C++加入GC,因为GC实在太有用了。

Bjarne Stroustrup认为如果一个特性对一些人有用,而且可能正确的使用,那么就可以加入。

但是这并不是正确的,用引用来代替指针也许能够减少不安全的空指针,但是引用给函数对象的各种相关包装带来了无穷的负担。这些负担只是为了做到“让一些用户可以用指针,但是同时也可以用引用”,虽然实际上引用和指针在二进制汇编是等价的。如果在所有情况下都是用指针而不是引用也不见得会给用户增加多少代码,但是可以肯定可以避免大量的关于引用的专门代码,这些专门代码有些甚至不仅是库编写者的责任,而且要求用户显式的编写的。

而且,对于C++这么复杂的一种语言,任何时候只使用C++的一个子集是一种实践的做法。但是,这个子集是哪个子集呢?你能找到恰好也使用这个子集编写的库吗?

对C++了解得越多,就越是对使用C++感到心惊胆战。

再抱怨一下标准库的流。前段时间想用标准库的流做一些定制,对标准库居然有这么龌龊的接口感到很震惊。首先是大量非正交而且龌龊的函数(看看这些函数命名吧:pptr epptr gptr pbump eback uflow sputn ...)然后是一些莫名奇妙的规则(wfstream并不会真正写入UCS-2编码的文件)

第二段有些笔误哦:-)

呵呵。我的项目任务很重的。
我除了吃饭睡觉写程序,剩下时间几乎全部来打理 blog 了 :D

顺便说一下,我每天看你的blog。似乎更新的慢了一些。不过要是写得太多,我就没时间看了。
很认同你的思路。

gc很有用。我有些地方也会有这样的需求。

Post a comment

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