火星日记 ~ 第七百九十九天 ~ 颓废啊

Lee.MaRS 发表于 2008-01-30 02:45:45

今年逃回家特别早,在家吃了睡睡了吃,颓废得很。

不过看到今年雪灾如此严重,火车站都堵疯了,觉得今年运气还是不错的。

在家到现在为此基本上没做什么事情,就打打游戏,看看电视,吃吃米粉,睡睡懒觉。

今天把libgc看了一下,大致明白怎么用了。

明天要不就看看libevent吧……
收藏: QQ书签 del.icio.us 订阅: Google 抓虾

[转载]关于 C++ 0x 里垃圾收集器的讲座

Lee.MaRS 发表于 2008-01-25 22:26:48

转载自http://blog.csdn.net/g9yuayon/archive/2007/07/23/1702694.aspx

好像最近C++标准地下工会在公司附近开会,所以我们上班时偶尔可以看到工会成员矫健的身影。我们也近水楼台,得以听到关于C++ 0x进展的一些科普报告。上次Bjarne Stroustrup做了关于泛型编程的讲座后,Symantec实验室的Michael Spertus也做了一个关于C++ 0x里垃圾收集的讲座。Michael Spertus当年写出了IBM PC上最早的C编译器,也是C++ 0x里垃圾收集器的主要倡议人。
 
Michael从什么是GC开始讲起。三言两语后,谈到在C++ 0x里加入GC的动机。一是许多数据结构,对象,或者资源的生命期难以事先确定、静态管理。我们需要某种形式的动态管理技术。很多老大以为C++高手的标志之一是不需要GC。如果这样想,Unreal的Tim Sweeney就笑了。Unreal引擎里就大量使用GC。 如果一个系统需要管理大量对象,要求高吞吐量,但可以容忍偶尔的系统延迟的话,GC是颇为不错的工具。所以3D/建模,2D图像处理等计算都可以用到 GC。第二个理由非常有煽动力:帮助C++程序清除内存泄露。我们不必在C++里排斥人肉内存管理。问题是,人肉内存管理难以尽善尽美。大型系统里内存泄 露几乎不可避免。每次泄露也不多,10来KB到几个MB。但积累起来,也就造成诸多问题。因为每次泄露量不大,也不像Java等基于GC的语言,“泄露” 随时都在发生。所以可以通过定期执行GC来清除这些泄露,也不用消耗过多资源。Michael后来举了一个颇有说服力的例子:某电信公司的交换机,100 多万行程序,有持续的内存泄露。每小时必须重启一次。使用GC后,内存泄露消失,交换机不用再定时重启。重启时系统堆上有大概200个线程,500MB内 存。这样算来,每线程每小时泄露2.5M。每线程每分钟不过42KB。而每分钟收集42KB内存对系统根本不会有什么影响。最后实测下来,收集500MB 不过需要两秒种。分摊到一个小时内,完全可以忽略不计。这样的GC应该叫LC—Litter Collector。还有一个例子是Michael向Mozilla浏览器里注入GC。每次用户操作使得GC回收大概10KB的内存,实在是小菜一碟。
 
Michael 接着谈到C++ GC的发展。C++ GC已经成熟,可以标准化了。系统研究的老大们已经做了20年的研究。GC也用到了形形色色的C++系统里。标准化的关键是C++的GC是可选项:GC可 以被关掉,而且程序员能够在代码里随时决定用GC还是人肉内存管理。这样才能满足某些系统实时回收资源的要求。而且已有的标准库就不需要重新编译。
 
Michael 比较了shared-ptr和GC。GC的主要缺陷是不能即时回收内存,而强项除了方便程序员外,就是性能了。GC的性能(尤其是分摊后的性能)在多方面 的基准测试里超过自动指针管理已经不是新闻。Michael举了Boost线程安全基准测试的数据。GC比用share-ptr的测试程序快10倍以上。 比Java的hotspot程序或者Gcj编译出的程序快5倍以上。甚至用人肉内存管理的C程序也比GC慢,不过比Boost的程序员快3倍左右。
 
既 然GC在C++里用了很多年了,干嘛还要标准化呢?主要有三条原因。一是内置的GC才能读取C++的类型系统。高质量的GC需要知道数据的类型信息。没有 类型信息,GC变得非常保守,需要经常扫描大片内存来决定是否能回收某个对象。这样让GC变得很慢。第二个原因是我们需要防止编译优化对GC造成破坏。如 果不标准化,标准的C++编译器不可能知道第三方的GC需要什么样的优化。第三是为了允许不同的厂家能共享GC管理的对象。不然微软在某个控件里用了 GC,怎么能保证同样的控件到了Borland的系统里也正常回收内存呢?
 
目前的C++ 0x的提议走的是稳健路线。任何功能都要经过实际应用的检验。GC用于特殊场合(比如前面的LC)。通过句法糖的方法实现,也就是说没有新的关键词。 API的数目要尽可能小。当然了,C++的类型系统不如Java那么强,所以GC也相应复杂一些。标准提案里包涵了好几种GC类型:
  • gc_required: 所有资源都要通过GC收集。由gc_required控制的区域内所有指针都是经过标注的gc指针。
  • gc_forbidden: 不允许GC。必须人肉回收内存。由gc_forbidden控制的代码区域里只有原始指针。
  • gc_safe:缺省情况。忽略人肉管理的内存,但处理没有被手工回收的部分。
  • gc_strict: GC处理的代码段里整型变量不包含指针(比如不能在DWORD里放指针)。
  • gc_relax: GC处理的代码段里整型变量可以包含指针。这种情况下GC往往需要扫描大量内存来确保安全回收内存。
  • gc_cast: 把一种类型的GC转换成另外一种类型。
下面是个例子:
class A {
            A *next;
            B b; // 这里不能用gc_strict, 因为我们不知道B里的数据信息。
            gc_stric int data[10000]; // 我们肯定data数组里没有指针
}
 
同 时C++标准库里还提供两个函数:bool std::is_garbage_collected(),和class std::gc_lock()。一个用来检查某块内存是否被GC回收,另外一块用来设定所谓的GC临界区。临界区内的内存不能被回收,这样可以防止GC不 合时宜地启动。
 
呵呵,够复杂吧?引入这么多操作的原因之一是要和老的C++系统互动。比如说下面一些情况:
  • 两个DLL,一个用了全局GC,另外一个没有怎么办?如果每个DLL都链接到自己的C类库怎么办?
  • 如果一个共享库希望在内部使用GC,但不影响堆的其它部分怎么办?
  • 如果我们在C++程序内调用libjvm怎么办?libjvm装载后,C++程序可以读取到载入的JVM里的堆,未必我们需要对已经有Java GC控制的内存再做垃圾处理?
针 对不同的情况,我们得祭出不同的GC。嘿嘿,C++程序员们,准备好你们的钱包哈。如果2009年后C++ 0x开始流行,要买的书就多了。比如Effective C++ GC, Master C++ GC, C++ GC with Legacy Applications,  Modern C++ Design with GC, Expert C++ with GC, Expert C++ without GC。这个世道,不容易啊。
 
那finalization嗫?没有了finalization的GC还叫GC么?C++的大仙们当然不会漏掉这么重要的环节。只不过因为finalization本身就很复杂了 (比如说回收内存时应该怎样调用回收对象的析构函数?如果回收时立刻调用,会造成线程不安全),所以有另外的提案讨论乐。
收藏: QQ书签 del.icio.us 订阅: Google 抓虾

火星日记 ~ 第七百七十九天 ~ 网络结束

Lee.MaRS 发表于 2008-01-10 17:47:24

全都复习到了。

全都没复习到。
收藏: QQ书签 del.icio.us 订阅: Google 抓虾

火星日记 ~ 第七百七十七天 ~ 图形学结束

Lee.MaRS 发表于 2008-01-08 11:15:04

777,在赌博机上一直都是最后的大奖。

不过在代表大奖的今天,对我来说却等于证明了一件事情。

那就是,

我是白痴。

悲剧年年有,今年又重演。

知道一个题会考,看了,考了,不会。

到底是哪个环节出了问题?

我在这种情况下都没能把握住分数。

可以去死了。
收藏: QQ书签 del.icio.us 订阅: Google 抓虾

火星日记 ~ 第七百七十天 ~ 2008.1.1

Lee.MaRS 发表于 2008-01-01 01:37:24

新的一年到来了。

感谢过去一年在我的身边的朋友们。

感谢你们容忍我经常在MSN上经常没头没脑地报怨,经常没日没夜地骚扰。

我承认我每次一遇到麻烦就会很急躁。

是你们的鼓励,让我坚持撑过每一次的考验。

再次感谢你们。

我会继续努力。:-)


收藏: QQ书签 del.icio.us 订阅: Google 抓虾