孟岩ID:myan
1628970次访问,排名8好友1人,关注者62
总是在思考存在的问题
myan的文章
原创 147 篇
翻译 0 篇
转载 3 篇
评论 5244 篇
最近评论
chengen81284493:很专业的一篇文章 非常的好 受益匪浅
jksharp:看的迷糊,我才做了一年的程序员,啥都学,我也很专业做的一门,难啊,老板啥都要我做,想写点程序都难,唉,今天要你配下服务器,明天叫你修改下数据库的数据,难
rawa459:补充几句,lua使用一个c语言的子集实现,没有发现枚举(较新版本的C才支持)、动态数组(C99才支持)等,就是这样一个c语言实现了足够强大的功能,我觉得比不上作者,作者是大学教授,并且有一个工作小组。什么时候国人学会平静对待C语言,不要那么浮躁不要那么张扬我们的教授级别的人物也能写出这样的东西,个人不喜欢C++,C和C++从最新的标准看已经决裂。C能够直接实现面向对象编程了,加上一些辅助库可……
rawa459:http://www.codingnow.com/2000/download/The%20Implementation%20of%20Lua5.0.pdf
看看此书,就知道lua的过人之处,本人也在写编译器,始终不敢碰基于寄存器的虚拟机,还是传统的基于堆栈的虚拟机。一个新语言,一个解释器不是很难,关键你要有过人之处,lua的函数闭包、协程、基于寄存器的虚拟机、关系表都是它的过人之处……
rawa459:http://www.codingnow.com/2000/download/The%20Implementation%20of%20Lua5.0.pdf
看看此书,就知道lua的过人之处,本人也在写编译器,始终不敢碰基于寄存器的虚拟机,还是传统的基于堆栈的虚拟机。一个新语言,一个解释器不是很难,关键你要有过人之处,lua的函数闭包、协程、基于堆栈的虚拟机、关系表都是它的过人之处,……
文章分类
收藏
    相册
    测试
    友情链接
    老赵的博客
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 垃圾收集机制(Garbage Collection)批判收藏

    新一篇: 对今年内将出版的几本C++书的简评 | 旧一篇: Traits技术:类型的if-else-then(STL核心技术之一)

    垃圾收集机制(Garbage Collection)批判

    在Java版发表这篇文章,似乎有点把矛头指向Java了。其实不是,GC是所有新一代语言共有的特征,
    Python, Eiffel,C#,Roby等无一例外地都使用了GC机制。但既然Java中的GC最为著名,所以天塌
    下来自然应该抗着。

    这篇短文源于comp.lang.java.programmer跟comp.lang.c++上发生的一场大辩论,支持C++和Java
    的两派不同势力展开了新世纪第一场冲突,跟贴发言超过350,两派都有名角压阵。C++阵营的擂主是
    Pete Becker,ACM会员,Dinkumware Ltd. 的技术副总监。此君精通C++和Java,开发过两种语言的
    核心类库,但是却对C++狂热之极,而对于Java颇不以为然。平时谈到Java的时候还好,一旦有人胆
    敢用Java来批判C++,立刻忍不住火爆脾气跳将出来,以坚韧不拔的毅力和大无畏精神与对手周旋,
    舌战群儒,哪怕只剩下一个人也要血战到底。这等奇人当真少见!我真奇怪他整天泡在usenet上,
    不用工作么?他的老板P.J. Plauger如此宽宏大量?Java阵营主角是一个网名Razzi的兄弟,另外有
    Sun公司大名鼎鼎的Peter van der Linden助阵,妙语连珠,寸土必争,加上人多势众,一度占据优势。
    C++阵营里大拿虽然很多,但是大多数没有Pete那么多闲工夫,例如Greg Comeau,Comeau公司老板,
    每次来个只言片语,实在帮不了Pete多大忙。但是自从C++阵营中冒出一个无名小子,网名Courage(勇气),
    发动对Java GC机制的批判,形势为之一变。C++阵营眼下处于全攻之势,Java阵营疲于防守,只能
    招架说:“你们没有证据,没有统计资料”,形势很被动。

    垃圾收集(GC)不是一直被Java fans用来炫耀,引以为傲的优点么?怎么成了弱点了?我大惑不解,定睛
    一看,才觉得此中颇有道理。

    首先,Java Swing库存在大量资源泄漏问题,这一点SUN非常清楚,称之为bugs,正在极力修正。但是看来
    这里的问题恐怕不仅是库编写者的疏忽,可能根源在于深层的机制,未必能够轻易解决,搞不好要伤筋动骨。
    不过这个问题不是那么根本,C++阵营觉得如果抓住对方的弱点攻击,就算是占了上风也没什么说服力。谁
    没有缺点呢?于是反其道而行之,猛烈攻击Java阵营觉得最得意的东西,Java的GC机制本身。

    首先来想一想,memory leak到底意味着什么。在C++中,new出来的对象没有delete,这就导致了memory
    leak。但是C++早就有了克服这一问题的办法——smart pointer。通过使用标准库里设计精致的auto_ptr
    以及各种STL容器,还有例如boost库(差不多是个准标准库了)中的四个smart pointers,C++程序员只要
    花上一个星期的时间学习最新的资料,就可以拍着胸脯说:“我写的程序没有memory leak!”。

    相比之下,Java似乎更优秀,因为从一开始你就不用考虑什么特殊的机制,大胆地往前new,自有GC替你
    收拾残局。Java的GC实际上是JVM中的一个独立线程,采用不同的算法策略来收集heap中那些不再有
    reference指向的垃圾对象所占用的内存。但是,通常情况下,GC线程的优先级比较低,只有在当前程序
    空闲的时候才会被调度,收集垃圾。当然,如果JVM感到内存紧张了,JVM会主动调用GC来收集垃圾,获取
    更多的内存。请注意,Java的GC工作的时机是:1. 当前程序不忙,有空闲时间。2. 空闲内存不足。
    现在我们考虑一种常见的情况,程序在紧张运行之中,没哟空闲时间给GC来运行,同时机器内存很大,
    JVM也没有感到内存不足,结果是什么?对了,GC形同虚设,得不到调用。于是,内存被不断吞噬,而那些
    早已经用不着的垃圾对象仍在在宝贵的内存里睡大觉。例如:

    class BadGc {

        public void job1() {
            String garbage = "I am a garbage, and just sleeping in your precious memory, " +
                      "how do you think you can deal with me? Daydreaming! HAHA!!!";
            ....
        }

        public void job2() {...}

        ...
        ...

        public void job1000() {...}

        public static void main(String[] args) {
            bgc = new BadGc();
     bgc.job1();
     bgc.job2();
     ...
     bgc.job1000();
        }
    }

    运行中,虽然garbage对象在离开job1()之后,就再也没有用了。但是因为程序忙,内存还够用,所以GC得
    不到调度,garbage始终不会被回收,直到程序运行到bgc.job1000()时还躺在内存里嘲笑你。没辙吧!

    好了,我承认这段程序很傻。但是你不要以为这只是理论上的假设,恰恰相反,大多数实用中的Java程序都有
    类似的效应。这就是为什么Java程序狂耗内存,而且好像给它多少内存吃都不够。你花上大笔的银子把内存
    从128升到256,再升到512,结果是,一旦执行复杂任务,内存还是被轻易填满,而且多出来的这些内存只是
    用来装垃圾,GC还是不给面子地千呼万唤不出来。等到你的内存终于心力交瘁,GC才姗姗来迟,收拾残局。而
    且GC工作的方式也很不好评价,一种方法是一旦有机会回收内存,就把所有的垃圾都回收。你可以想象,这要
    花很长时间(几百M的垃圾啊!),如果你这时侯正在压下开炮的按钮,GC却叫了暂定,好了,你等死吧!另一
    种方法,得到机会之后,回收一些内存,让JVM感到内存不那么紧张时就收手。结果呢,内存里始终有大批垃
    圾,程序始终在半死不活的荡着。最后,GC可以每隔一段时间就运行一次,每次只回收一部分垃圾,这是现在
    大部分JVM的方式,结果是内存也浪费了,还动不动暂停几百毫秒。难啊!

    反过来看看C++利用smart pointer达成的效果,一旦某对象不再被引用,系统刻不容缓,立刻回收内存。这
    通常发生在关键任务完成后的清理(cleanup)时期,不会影响关键任务的实时性,同时,内存里所有的对象
    都是有用的,绝对没有垃圾空占内存。怎么样?传统、朴素的C++是不是更胜一筹?

    据统计,目前的Java程序运行期间占用的内存通常为对应C++程序的4-20倍。除了其它的原因,上面所说的是一个
    非常主要的因素。我们对memory leak如此愤恨,不就是因为它导致大量的内存垃圾得不到清除吗?如果有了
    GC之后,垃圾比以前还来势汹汹,那么GC又有什么好处呢?

    当然,C++的smart pointer现在会使用的人不多,所以现在的C++程序普遍存在更严重的memory leak问题。
    但是,如果我奶奶跟舒马赫比赛车输掉了,你能够埋怨那辆车子么?

     

    发表于 @ 2001年04月20日 13:01:00|评论(loading...)|编辑

    新一篇: 对今年内将出版的几本C++书的简评 | 旧一篇: Traits技术:类型的if-else-then(STL核心技术之一)

    评论

    #周星星 发表于2004-09-03 16:02:00  IP: 218.2.111.*
    孟大师在前,我也说说我的感想,批评一下GC,如果说的不对,请海涵
    (以下文中的“你”不是指孟大师,而是代指GC支持者)
    1。垃圾自动收集仅仅是垃圾回收机制中的一种,即使它比其他机制都容易使用,那么GC也不可能成为统一的方法,因为它缺乏效率,Bjarne说过一句话,大体意思是:可以将一个本身效率很高的东西牺牲它的部分效率以提升它使用的方便性,但无法将一个本身就缺乏效率的东西牺牲方便性来提高效率。这很容易理解,比如MFC分封了windows api,而不是windows api来封装MFC。
    2。垃圾自动收集不是Java发明,据我所以它是C语言所发明,尝试过无数次,至今仍在研究中。所以我说如果C语言认为GC还没有足够成熟到可以普遍应用的地步,那么Java更不可能。
    3。为什么要将一种不能放之四海而皆准的机制加入到语言中呢?这样只能拖累语言本身。Java中只能GC,但如果是C/C++它可以自己管理内存,也可以交给其他模块去管理,GC for C/C++ 有很多产品了,免费的也有不少,她们都比Java的GC更健壮,毕竟C语言研究GC最早,且C语言是开放的,有无数的专家参与建设。
    4。内存应该交给谁来管理?这要分两种情况:a.如果内存对你而言并不重要,且你对内存的管理水平比之于计算机更糟糕,那么你应该去使用GC;b.如果内存对你而言很重要,或者你对内存的管理水平比死板的计算机好,那么你就不应该使用GC。记住,即使死板的计算机程序比你智商更高,它也不可能做得比你好,因为它的处理程序必需通用,必需要为通用性牺牲性能。
    5。手动的内存回收真的是很麻烦吗?我使用C++很多年,可以说我写的程序重来没有过内存泄漏,更主要的是我也没有花费太多的精力在内存管理上,因为“构造即初始化”,而我只要告诉它在析构的时候delete内存就可以,方便而高效。
    6。GC真的安全吗?孟大师说Java有内存泄漏问题,这我没有亲眼所见,但我现所在公司里的C#程序却有着非常严重的内存泄漏,连续运行两个月之后就耗尽内存。
    7。GC中的G是什么?应该是垃圾而不仅仅是内存吧?!但Java做到了吗?也许以后会实现,但我永远不相信GC能将进程锁之类的垃圾自动回收掉,因为进程锁之类的资源的创建和销毁是需要实时性的,即使将来实现了,它和现的内存GC的机制也不会相同,有几类资源,你就得创造几类自动回手机制,你知道有几类吗?即使你能知道,你也无法预知将来是不是有新种类的资源。
    8。为什么要将内存和其他资源的管理办法分开了,为什么不学学C++,通过构造析构机制统一所有的资源管理办法?
    #hehe 发表于2005-01-04 23:09:00  IP: 202.103.41.*
    "垃圾自动收集不是Java发明,据我所以它是C语言所发明,尝试过无数次,至今仍在研究中。所以我说如果C语言认为GC还没有足够成熟到可以普遍应用的地步,那么Java更不可能。"

    我感到脸红,为你们。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 孟岩