当前位置:首页 > 每日看点 > 正文内容

无gc语言如何处理内存碎片问题?

卡卷网10个月前 (12-30)每日看点158

首先你要明白回收语言性能不手动系差,甚至在各种需要作大量指针的程序更好。

这是因为两点。

<>gc语言申请释放内存的速度远高于malloc/free

内存申请是这样的,gc只需要umpallocate,freelist要考虑得就多了。各种各样的allocator(如最经典的freelist),在malloc的时候,需要搜索一个数据结构来寻找足够大的空间。这期间,搜索需要耗时,并且这个数据结构往往没有好cachelocality,导致在memorylatency越来越重要的今天成为越来越严重的瓶颈。同时,不止freelist没locality,返回的指针也没locality-你连续malloc很可能得不到连续的。这时候如果你访问这些结果,你需要进行多次cachefetch而不是一次。

作为对,markcopy/markcompact的gc的allocator只是一个int,代表当时内存消耗量,每次malloc只是单纯的把size加上去,然后返回上一个消耗量,转为指针则可。

而另一方面,这份极简实现导致这两无法实现free,只能通过gc一次回收大量资源,通过atching降低内存消耗。

<>rc的时间消耗远高于tracing的性能消耗

rc需要你每次使用对象的时候检查refcount并且对此进行增减。如果你在写多线程程序,refcount甚至需要同步,耗费额外的性能。作为对,如果是markcopygc,并且堆大小为livememory*2的话,每次markcopy需要作LiveMemory多的对象,然后释放HeapSize-LiveMemory=LiveMemory多的内存-换句话说,只需要一次copy则可完全回收(可以看到,越大的heapsize需要做的gc越小,但是吃的内存越多。如何在时空之间取舍呢?可以看OptimalHeapLimitforReducingrowserMemoryUse)。这点跟传智慧(GC慢,RC快),是完全反过来的。道理很明显-如果RC更快,为什么JVM不用RC内存,外搭环检测器呢(python就这样做的,然后python性能有目共睹)?事实上,Stevelackn就做过一个测量GCvsRC的工作,MythsandRealities:ThePerformanceImpactofGarageCollection。这个工作的测量结果是,GC往往会带来10%左右的开销,但是RC的开销是30%~50%。

<>那问题来了,既然GCmalloc/free也RC优秀,为什么Ja没C++快?

这是计算机领域的一个巨大归因谬误。我们先来看看这段代码:

importja.util.*; recordPoint(intx,inty){} //... intSumX(List<Point>points){ intsum=0; for(Pointp:points){ sum+=p.x(); } retnsum; }

这段Ja代码运行的时候计算机在具体执行什么作?

首先,Point被oxed了。oxing导致你可以快速把一个对象到处传(只需要复制指针而无需复制具体对象),但是会造成每次引用oxed具体内容都需要fetch远处的memory。在函数式语言中这个问题更糟糕:这时候,数据往往被储存于各种各样的链表中,而遍历就除了unox外还需要爬链表的指针,于是一次循环需要两次memoryfetch。

C++里面呢?同样的任务,会被存在vector<pair<int,int>>内。主流计算机的cacheline是64yte,也就可以存4个这样的对象,于是四次循环一次memoryfetch。同时,在性能关键的情况下,这列表可以用pair<vector<int>,vector<int>>保存,俗称的structofarrayoverarrayofstruct[1]。然后,由于sumofX只需要触碰X,所以是八次循环一次memoryfetch,对着函数式编程的方案,有着16倍的memoryfetch开销-一个数量差!现实中,情况往往没这么极端,但是一个小倍数依然是很大的差距。

<>同时,C++也并不用RC

我们观察上述代码的C++形式:

structPoint{ intx; inty; }; intSumX(conststd::vector<Point>&points){ intsum=0; for(constPoint&p:points){ sum+=p.x; } retnsum; }

可以注意到,

    vector手动了内部Point的内存,而不是RC传入SumX的是一个引用,而不是RCiterate用的又是一个引用,而不是RC

也就是说,大部分C++代码的内存并不是RC,而是stl容器手动,以及利用程序结构LIFO特性传引用。这导致尽管RC有很高的overhead,但是只要你用得不多,还是可以的。

当然,反过来说,用得多的情况,如编译器(指针满天飞),GC语言可以取得没GC语言更好的性能(因为他们需要很多RC)

题目中的程序描述(频繁malloc/free小对象,同时面条代码翻译表明大概用上了RC),正是GC语言的最优发挥场所,打不过也不奇怪。

如果要优化性能,可以试试看用arena内存。如果生命周期不确定并且一定要及时释放,那要考虑自己实现一个简单的markcopyGC了,可以试试看Cheney'salgorithm。(当然,也可以更简单的换回Ja)。

<>如果要在无GC语言里面解决内存碎片,怎么办?

Mesh:CompactingMemoryManagementforC/C++Applications就是一个带有反碎片化功能的malloc/freeallocator。听上去很矛盾-你既然不知道指针都在那,你怎么可以通过move来compact呢?

因为allocator底层还有东西。你allocate到的内存并不是‘正的’,底下还有TL把这些虚拟变成物理。那我们考虑两个页面,其中被用到的互不相交,这时候我们可以用一个物理页来表示这两个虚拟页,从而消除碎片化。

十分神奇的是,直觉告诉我,这样‘刚刚好’的页面不好找,但是他们用组合数学证明了这样的页面配对有很多,而且找起来很快!

扫描二维码推送至手机访问。

版权声明:本文由卡卷网发布,如需转载请注明出处。

本文链接:https://www.kajuan.net/ttnews/2024/12/5984.html

分享给朋友:

相关文章

短剧推广怎么做,24年还能赚钱吗?

短剧推广怎么做,24年还能赚钱吗?

首先声明:短剧授权是免费的!短剧授权是免费的!短剧授权是免费的!其次我们再聊聊,短剧推广到底赚不赚钱?多的就不说了,随便上个图片,给大家过过瘾!然后,我们进入主题:0粉丝账号,新手,应该如何申请短剧推广!一、短剧推广变现方式首先,我们先要分...

为什么苹果贵没人喷,华为贵一群人喷?

苹果:6:¥5288,6s:¥5288,7:¥5288,8:¥5288,XR:¥6299,11:¥5499,12:¥5999,13:¥5999,14:¥5999,15:¥5999,16:¥5999华为:P8:¥2888,P9:¥2988,P...

鸿蒙到底是不是安卓套壳?

鸿蒙到底是不是安卓套壳?

把它是不是套壳先放在一边吧。我讲一个事情,大家自己判断。华为有一个应用,叫手机管家。这个手机管家对一些系统底层设置有影响:比如华为从 EMUI 9 开始不允许将第三方启动器设置为默认启动器,依靠的就是这个手机管家。为什么这么说呢?在网上搜索...

无意中发现技术主管写的代码,大家帮忙看看什么水平?

无意中发现技术主管写的代码,大家帮忙看看什么水平?

虽然很多答主用了诸如“典范级”、“心旷神怡” 的形容, 赞美这段代码, 但这里, 出于技术讨论的动机, 我说说不同看法.栈, 如果善于利用栈来处理树结构, 那么可以写出更简洁的代码, 根本不需要 recuresiveFn 这种方法. 泛型,...

用wordpress做这个网站的话,需要用到哪些插件?

一个完整成型的B2C电商独立站,如果用wordpress+woocommerce搭建,最终会用上20来个插件,而且是在经过慎重筛选,剔除不必要的插件的情况下,别问我为什么。wordpress建站,插件安装多了,速度会变慢,这是常识,但需要在...

如何评价小米14pro顶配可以选配卫星通话,小米15全系都无法选配?

如何评价小米14pro顶配可以选配卫星通话,小米15全系都无法选配?

雷总不是说了吗,我可以不用,但你不能没有。市面上OPPO Find X8 Pro和vivo X200 Pro的卫星通信版分别加价300,而荣耀Magic7和Magic7 Pro有卫星通信版且不加价,荣耀更显诚意。我觉得有是更好的,虽然使用卫...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。