??xml version="1.0" encoding="utf-8" standalone="yes"?>久久精品无码免费不卡,久久午夜福利无码1000合集,亚洲精品无码久久久久sm http://www.shnenglu.com/Chipset/category/9270.htmlWelcome to Chipset's homepage!
zh-cn Thu, 23 Apr 2015 12:05:50 GMT Thu, 23 Apr 2015 12:05:50 GMT 60 垃圾攉--从算法角度去?/title> http://www.shnenglu.com/Chipset/archive/2015/04/20/210402.htmlChipset Chipset Mon, 20 Apr 2015 09:21:00 GMT http://www.shnenglu.com/Chipset/archive/2015/04/20/210402.html http://www.shnenglu.com/Chipset/comments/210402.html http://www.shnenglu.com/Chipset/archive/2015/04/20/210402.html#Feedback 0 http://www.shnenglu.com/Chipset/comments/commentRss/210402.html http://www.shnenglu.com/Chipset/services/trackbacks/210402.html 其实垃圾攉是对于无用?也称作死亡的)对象释放掉他们占用的资源。无论Javaq是C#q是脚本语言Q还是其他,垃圾攉无非׃四个法Q下面分别介l?p style="background-color:transparent;">1. 引用计数
一 个对?本文里对象都是广义的对象Q不是专指用classcd创徏的变量,下同)刚创建时Q计数器(用一个整数变??Q引用一ơ计数器?Q过期减 1Q右值引用[请参考C++11标准里的叛_引用概念,如果你不明白的话]一ơ减1Q当计数器降?时该对象q期Q回收掉他占用的资源?/p>
原理十分单,实现h也容易,其对于大对象,直是l配Q计数器是共享变量,通常用一个整型变量表C,它的加减用原子操作就能搞定,速度很快。再者就是实时性很好,引用加1Q不引用减1Q过期就消失?/p>
?于小对象来说׃爽了Q比如一个字W,占用的内存比计数器还,对于对象都从堆上创徏的语aQ例如JavaQ不太合适。另外一个缺Ҏ(gu)循环引用比较ȝQ?此时计数器永q不会降?Q此时会D内存泄漏。早期的COM漏内存就是因个原因,Perl里至今对象都不能循环引用Q否则漏内存。解x案也有,?参考C++11里的weak_ptr和boost里的weak_ptr实现?/p>
2. 标记清理
看名字就能明白,像打标{。定期的扫描堆上的对象,把一个对象分成三个阶D?从数学角度来看是三个集合) ??白处理,黑表C占用状态,白表C无用状态,C于二者之_白表C可以回收了。实际实C可能q不严格按照理论上这样区分哦?/p>
不停的扫描会耗费太多的资源,长时间不扫描则可能堆内存耗尽Q这个扫描时机是个问题。扫描实际有的设计成d触发Q有的设计成旉触发。不计成哪种都不能保证很完美Q因为收集器也是应用E序(从操作系l内核的角度ȝ)Q也接受调度Q由于收集的是一个对象的集合(通常是一ơ收集多个对象占用的资源)Q因此实时性不太好保证Q尤其在单核心的q代和计能力不太强的嵌入式领域ؓH出?/p>
什么事情有~点有优点Q多核心的年代就好多了,其当CPU占用率不高且内存比较大时Q这标记清理的做法可能还是比较不错的?/p>
3. 拯
最好理解的是半堆拯Q内存一分ؓ二,一Ҏ(gu)有用对象一Ҏ(gu)无用对象。从堆空?L上搜索进E的U性地址I间Q我q里是那个意?的一端开始,不停 的把zȝ的对象复制到另外一端,{这辚w剩死的对象时Q把q段I间(一半堆内存)标记为空闌Ӏ考虑内存利用率和处理速度原因Q实际实C很多时候可不一?采用半堆的做?可能采用1/N堆,N>2)Q这里是Z便于理解才用半堆做例子?/p>
复制对象很好,但是复制大对象会比较慢。复制貌似最_劣最不好的垃圾收集算法,其实不然Q想惛_用计数和标记清理都不搬运对象Q因此长旉q行(x服务器能动不动就x吗?)会生很多内存碎片,而复制的做法则相当于压羃内存Q降低内存碎片,提升内存利用率。想x端情况下吧,本来有接q?GB内存I??假设有个2字节的对象刚好位于中?Q此时申?12MB以上的堆内存会注定失败,因ؓ没有q箋?12MB内存可用。上q其他算法都解决不了q种问题Q?复制攉的做法却能很好的解决q种问题?/p>
对于有指针的C和C++Q复制的攉法没法用,因ؓq会D指针(zhn)挂和野指针Q对于Java{,q种攉法也许很不错。跟标记清理cMQ由于一ơ收集多个对象占用的资源Q实时性也是个问题?/p>
4. 分代攉
严格的说分代攉不应该算法Q应该算{略?br style="background-color:transparent;" />
误虑人的家谱pҎ(gu)理解多了Q或者考虑数据l构中的树层ơ结构,道理cM。对象也可以分代Q显然越q轻的对象越Ҏ(gu)?误虑作用域的概念Q或者想想C++QJava{程序里大括弧里和嵌套的变量也行)。分代收集是后来才引入的QJava和C#里都有采U뀂实际效果表明,分代攉比上面那三种中的L一U收集算法都好用Q尤其复杂对象比较多时更是如此,抛开实时性不谈,臛_q_速度比较快?/p>
现实中,商用领域没有一U垃圾收集算法特别适合所有场合,多数垃圾攉器都采用多种法l合来设计。多数垃圾收集器都是q发执行的,有的设计则是一个线E始l在攉垃圾内存Q尤其在多核的年代更是如此?/p>
垃圾攉优缺?/strong>
?圾收集带来了C的好处Q尤其从软g工程的角度去考虑Ӟ好处太多了,q就不多|嗦了,但是也会降低E序执行速度Q尤其在实时性要求高的场合,真就没少见用垃圾攉器的Q或者这栯Q在高实时性的应用里,用C和C++和汇~,在一般场合下用Java,C#甚至脚本都行?/p>垃圾攉会带来额外的内存开销Q我觉得q是数据化比较容易理解,理论上同L法下Q有3倍以上的内存ӞJava代码可以辑ֈC++代码?0%以上速度Q如果想辑ֈ同样的速度QJava代码需要消?倍于C++代码耗费的内存。注意是理论上,实际中可能还不止q个数?/div>
]]>Why Java Will Always Be Slower Than C++? http://www.shnenglu.com/Chipset/archive/2008/12/18/69739.htmlChipset Chipset Thu, 18 Dec 2008 09:20:00 GMT http://www.shnenglu.com/Chipset/archive/2008/12/18/69739.html http://www.shnenglu.com/Chipset/comments/69739.html http://www.shnenglu.com/Chipset/archive/2008/12/18/69739.html#Feedback 0 http://www.shnenglu.com/Chipset/comments/commentRss/69739.html http://www.shnenglu.com/Chipset/services/trackbacks/69739.html
Why Java Will Always Be Slower than C++
by Dejan Jelovic
"Java is high performance. By high performance we mean
adequate. By adequate we mean slow." -
Mr. Bunny
耍过JavaE序Q或者用Java码过E序的h都晓得,Java要比用C++写成的原生程序要慢。这是咱用Java时已l承认的事实?br> 不过Q很多h惌说服我们说这只不q是暂时的,他们说Java从设计上来讲q不慢,相反Q只是现在的JIT实现相对比较嫩,有很多能优化的地方JITq没有优化到Q拖了后ѝ其实不Ӟ不管JIT们多牛,Java永远要比C++慢?br> 我想?.. 宣扬Java不慢于C++的h往往是觉得,Q语法)严格的语aQ可以让~译有更大的优化I间。因此,除非你想做h肉编译器优化整个E序Q否则通常都是~译器做得更好?br> q是真的。在数D领域,Fortran仍然胜于C++Q的因为它更严根{不用担心指针瞎搅和Q编译器可以更安心地优化。C++x败Fortran的唯一办法Q就是好好设计一个像Blitz++那样的库?br> 试...
Java可以跟得上C++的地方,是基准试。计vWN个斐波纳契数Q或者运行vLinpackQJava没理׃跟C++跑得一样快。当所有的?
都攑֜一个类里,q且只用基本的数据cdQ比如说int或者doubleӞJava~译器的能跟得上C++的脚步?br> 事实... 当开始在E序中用对象的时候,Java放松了潜在的优化。这一节会告诉你ؓ什么?br> 1. 所有的对象都是从堆里分配的?br> Java从栈里分配的Q就只有基本数据cdQ如intQ或者doubleQ还有对象的引用。所有的对象都是从堆里分配的?br> 当有大量语义上是一回事的对象时Q这不成问题。C++同样也是从堆上分配这些对象。但是,当有D义不同的对象时Q这是一个主要的性能杀手?br>
什么是对象?Ҏ(gu)来说Q就是P代器们。在设计中,我用了很多P代器。别人可能会用复数?DE序员可能会矢量或者点cR处理时间序列的人可能会有时?
cR用这些类的hQ无一例外地讨厌把不费旉的栈上分配换成花费固定时间的堆上分配。假如把它放在一个@环里Q就变成了O(n)?了。如果再加一层@
环,没错Q又变成O(n^2)?了?br> 2. 大量的{换?br> 得益于模板,好的C++E序员甚臛_以写于完全没有{换的牛程序。不q,Java没有模板Q所以Java代码L充满了{换?br> 对于性能Q它们意味着什么?呃,在Java里所有的转换都是很费时的动态{换。多Ҏ(gu)Q想想你可能会怎么样实现{换的Q?br> 最快的Ҏ(gu)是Q给每一个类赋g个序P然后用一个矩阉|描述L两个cL否相关的。如果是的话Q需要给指针加上多少的位UL能进行{换。这U方法的伪码看v来应该是q样的: DestinationClass makeCast (Object o, Class destinationClass) { Class sourceClass = o.getClass (); // JIT compile-time int sourceClassId = sourceClass.getId (); // JIT compile-time int destinationId = destinationClass.getId (); int offset = ourTable [sourceClassId][destinationClassId]; if (offset != ILLEGAL_OFFSET_VALUE) { return <object o adjusted for offset>; } else { throw new IllegalCastException (); } } 好一堆代码。这只是一个简单的情景——用矩阵来表C类的关pL费了一部分内存Q没有哪个成熟的~译器会q样子做。他们会使用map或者遍历承树Q这样会变得更慢?br> 3. 攀升的内存占用?br> JavaE序储存数据占用的内存大概是相当的C++E序的两倍。原因如下: 1. 启用了垃圾收集的E序一般都比不使用垃圾攉的程序多?0%的内存?br> 2. 本来C++里在栈上分配的对象,CJava在堆上分配了?br> 3. Java对象比较大,因ؓ所有的对象都有一个虚表,q要加上对(U程Q同步的原生支持?br>大的内存映像让程序更大概率被攑ֈ盘的交换区厅R没有什么比交换文g更慢的了?br> 4. ~少更细致的控制?br>Java原来是作ؓ一U简单的语言来设计的。很多在C++里让E序员控制细节的Ҏ(gu)在Java里都被一脚踢开了?br> 比如_在C++里可以改q引用的位置(?)。或者一ơ申请和释放很多个对象。或者用指针耍一些小技巧,更快地访问成员?br> 5. 没有高层ơ的优化?br> E序员处理高层次的概c而编译器处理剩下的低层次概念。对于程序员来说Q一个叫Matrix的类׃表了比一个叫Vector的类更高层次的概c而对于编译器来说Q这些名字都是符可的一个入口。他们只兛_c里面有哪些函数Q函数里面有哪些语句?br> q样想一下,比如说要实现一个exp(double x, double y)函数Q计出x的yơ幂。对于一个编译器Q它能只看一下这个函敎ͼ然后指出Qexp(exp(x, 2), 0.5)可以优化成x自己吗?当然不行?br> ~译器能做的优化只是语句层面的,而y是在~译器里面的。即使程序员知道两个函数是对U的Q可以把它们都消去,或者函数的调用序只是相反的,除非~译器能只瞄一下语句,然后指出来,不然优化是不可能完成的?br> 所以,如果惌完成一个高水^的优化,必须存在某种Ҏ(gu)Q可以让E序员来告诉~译器优化的规则?br>
没有哪个行的程序语a/pȝ可以做到q点Q至已知的Ҏ(gu)Q比如微软承诺的语言Q都不能。即便如此,在C++里可以用模板元编E来实现寚w层次?
象的优化。时消除,部分求|对称函数调用的消去,和其它可以用模板实现的优化。当Ӟ不是所有的高层ơ优化都可以q样做。ƈ且实现这些东西相当麻烦?
但是大多数都可以完成Q有人已l用q些技术实C好些旉的库?br> 不幸的是QJava没有M元编E的特质Q因此在Java中不会有q种高层ơ的优化?br> 所?.. ׃存在q种语言Ҏ(gu),Java不可能达到C++q种速度。这相当E序上暗CZQ对于要求高性能的Y件和竞争Ȁ烈的COTS舞台上,使用Java不是一U明智的选择。但是因为它和缓的学习曲U,它的定wQ和它庞大的标准库,所以适合开发中型自用和定制Y件?br> 附记... 1. 有h向James GoslingQ谁Qgoogle?..Q提交了很多可以改进Java性能的语aҎ(gu)。文本在q里。不q的是,Java语言已经有四q没有改动过了,所以看hq些提议g不会在一夜之间被实现?br> 2. 最有可能往Java里加入泛型的是Generic Java。又很不q的是,GJ只是通过在编译时把所有类型信息去掉来支持泛型。所以最后面执行环境看到的,仍然是缓慢的转换?br> 3. 垃圾攉的FAQ包含了关于垃圾收集慢于定制分配器的信息(上面W四点)?br>
4. q里是一宣U垃圾收集比栈分配的快的文章。但是它的要求是物理内存必须是程序实际需要的内存的七倍之多。还有,它描q的是一Ustop-
and-copyQ是不是那种执行C半,然后停下来,把内存拷到另外一块内存,同时清除垃圾的那U方法?Q,而且q不是ƈ发的?br> 反馈... 我收到很多关于这文章的反馈。附上一些典型的评论Q还有我的回{: “你还忘记了指出在Java里所有的Ҏ(gu)都是虚方法,因ؓ没有Z加上final关键字?#8221; 事实上,不用final关键字不是问题的关键所在,使用者才是。同Ӟ虚函C没有问题Q但是却失去了优化机会。自从JIT们知道怎么样内联虚函数Q这变得不那么显著了?br> JIT可以内联虚函敎ͼ所以Java可以比C++更快?br> C++也可以用JIT~译。不信的可以看看.NET的C++~译器?br> 到最后的时候,速度q不重要。电(sh)脑浪费了大部份时间在{待用户输入?br> 速度仍然很重要。我仍然在等我的W记本启动v来,我在{我的编译器停下来,我还要等Word打开一个超长的文档?br> 我在一个金融公司工作。有时候我必须对一个很大的数据集进行模拟。速度在这U情况下都很重要?br> 有些JIT可以在栈上分配一些对象?br> 当然Q一些?br> 你的转换代码看v来很丑。可以在cȝl承层次上检查类?br> 首先Q这样只比矩阉|扑ֿ一点点而已?br> W二Q这样只能查扄Q类只占多少Q低层次的细节往往是通过接口来实现的?br> 哈,那么我们都应该用汇~? 不是的,我们都要使用对业务有用的语言。Java提供了庞大的标准库,让很多Q务变得容易,因此Java是伟大的。它比其它所有的语言更容易移植(但ƈ?00%可移植——不同的q_有不同问题)。它h垃圾攉机制Q简化了内存理Q同时也让某些构造如闭包可实现?br> 但是Q同ӞJava和所有的语言一P也有瑕疵。在D义的cd上缺支持。它的同步ƈ不是很有效率。它的标准库建立在异常检查之上,把实现拖q了接口。它的性能可以更好。它的数学库有些gh的问题。诸如此cR?br> q些~憾都是大问题吗Q看你用它做什么。因此,在几U语a里,q同它的~译器以及可以选择的类库里选择对你的工E有利的一U?br> 原文见:http://www.jelovic.com/articles/why_java_is_slow.htm [林杰杰翻译,不是?Chipset)译,我仅仅是拯林杰杰的Q] ]]>
ɫþþ99Ʒ91 |
ɫþˬˬƬAV |
ƷɫۺϾþ |
ձѾþþþþþվ |
ɫۺϾþ |
þþþþ˸߳ӰԺ |
þþŮһ |
99ȾƷþֻоƷ |
˾ƷۺϾþþþ
|
鶹WWWþöڲƷ |
˾þô߽ۺAv |
91鶹Ʒ91þþþþ |
þþŷղAV |
Ʒ99þþƷ |
ҹƷþþþ |
Ʒþþþþù |
Ļþҹ |
ŷƷþø |
seguiþùƷ |
þ99Ʒþþþ |
þþƷ99Ʒ |
ɫ͵͵888ŷƷþþ |
avԾþþþa鶹 |
ȾþùŷһƷ |
99þþƷѾƷһ
|
þþþþþþþѾƷ |
þþƷ77777 |
Ʒҹvaþ |
þþþavëƬ |
þҹɫtvվ |
þۺ˿ձ |
þþƷһ |
99999þþþþ |
vaþþþͬ |
뾫ƷþɪӰ |
ŷƷ˾þԻӰƬ |
þһٸ |
þ99Ʒþþþþ9 |
Ʒ۲ӰԺþ |
Ʒþþþþþþþ |
þòþüӰԺwwwձ |