码迷,mamicode.com
首页 > Windows程序 > 详细

C# 内存管理优化畅想(一)---- 大对象堆(LOH)的压缩

时间:2015-10-08 18:20:14      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

    我们都知道,.net的GC是不会压缩大对象堆的,因为其时间开销不可接受,但这是以大对象堆产生大块碎片为代价的,如果以后要分配的大对象比最大的碎片还大,那么即使它比所有碎片的总大小要小,也是无法在不扩展大对象堆的前提下分配成功的,此时有可能引发内存不足的异常。

    我想到一个方案,可以让大对象堆也能压缩,而且时间开销在可接受的范围内,原理是利用页表。我们知道,程序能看到的内存地址都是虚拟地址,是通过页表映射到物理地址的,连续的虚拟地址对应的物理地址未必连续,反之亦然。在内存中移动大量数据,开销很大,因为数据真的要在物理内存上复制,但如果我们不动物理内存上的数据,只修改页表及其缓存TLB,即修改了物理地址与虚拟地址的映射关系,开销就会小得多,而且对于应用程序来说,同样达到了内存移动的效果。(物理内存上没有数据移动,但对象的虚拟地址却变了,对应用程序来说,这就是数据移动了!)

    当然,如果要用这种方法实现压缩大对象堆,也会有一些局限性:比如每个大对象必须占据整数页的空间,且大对象的起始地址必须是某页的起始地址,这样大对象之间会出现一些小碎片(不会超过一页的大小,即不超过4K,与85K以上的大对象本身相比,还是很小的),但小碎片总比大碎片好呀,就看怎么权衡了,而且这些小碎片也是可以被利用的,比如可以把一些大小合适的2代小对象存储到这些小碎片中,以节约小对象堆的空间。

    PS: 现在的一些虚拟机软件的实现似乎就使用了类似的方法,以达到提高效率的目的。 

    该问题的英文讨论贴:https://github.com/dotnet/coreclr/issues/555

C# 内存管理优化畅想(一)---- 大对象堆(LOH)的压缩

标签:

原文地址:http://www.cnblogs.com/ygc369/p/4861610.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!