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

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

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

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

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

C# 内存管理优化畅想(一)---- 大对象堆(LOH)的压缩的更多相关文章

  1. C# 内存管理优化畅想----前言

    C#语法简洁.优雅,类库丰富,是我最喜爱的计算机语言,没有“之一”.但是,经过深入学习后发现,C#的内存管理,也就是通常所说的垃圾回收(GC)机制,虽然跟其他支持GC的语言相比,已经很优秀了,但与手动 ...

  2. C# 内存管理优化畅想(二)---- 巧用堆栈

    这个优化方法比较易懂,就是对于仅在方法内部用到的对象,不再分配在堆上,而是直接在栈上分配,方法结束后立即回收,这将大大减轻GC的压力. 其实,这个优化方法就是java里的逃逸分析,不知为何.net里没 ...

  3. C# 内存管理优化畅想(三)---- 其他方法&结语

    前两篇文章提出的优化方法,都是不需要修改源代码的,而是在CLR或JIT层面进行自动优化的.但本文中提出的优化方法则需要引入新的语法,开发者只有在源代码中使用了这些新语法,才会获得优化. 1. 允许对象 ...

  4. [翻译] 编写高性能 .NET 代码--第二章 GC -- 减少大对象堆的碎片,在某些情况下强制执行完整GC,按需压缩大对象堆,在GC前收到消息通知,使用弱引用缓存对象

    减少大对象堆的碎片 如果不能完全避免大对象堆的分配,则要尽量避免碎片化. 对于LOH不小心就会有无限增长,但LOH使用的空闲列表机制可以减轻增长的影响.利用这个空闲列表,我们可以在两块分配区域中间找到 ...

  5. oc45--多对象内存管理 优化

    // // main.m // Set方法的内存管理 #import <Foundation/Foundation.h> #import "Person.h" #imp ...

  6. C# 内存管理优化实践

    内存优化畅想系列文章已经结束了,很多读者读完之后可能觉得“然并卵”,毕竟都是给微软提的建议而已,现在都没有实现.那么为了优化内存,有没有什么我们现在就能用的技巧呢?我的答案是:有.网上关于.net内存 ...

  7. EasyDarwin开源流媒体服务器内存管理优化

    -本文由EasyDarwin开源团队成员Fantasy贡献 前言 最近在linux上跑EasyDarwin发现一个很奇怪的问题,当有RTSPSession连接上来的时候,发现进程的虚拟内存映射一下就多 ...

  8. 一文了解.Net的CLR、GC内存管理

    一文了解.Net的CLR.GC内存管理 微软官方文档对内存管理和CLR的概述 什么是托管代码? 托管代码就是执行过程交由运行时管理的代码. 在这种情况下,相关的运行时称为公共语言运行时 (CLR),不 ...

  9. .Net 垃圾回收和大对象处理

    CLR垃圾回收器根据所占空间大小划分对象.大对象和小对象的处理方式有很大区别.比如内存碎片整理 —— 在内存中移动大对象的成本是昂贵的,让我们研究一下垃圾回收器是如何处理大对象的,大对象对程序性能有哪 ...

随机推荐

  1. 关于@synchronized(self)的用法

    @synchronized 的作用是创建一个互斥锁,保证此时没有其它线程对self对象进行修改.这个是objective-c的一个锁定令牌,防止self对象在同一时间内被其它线程访问,起到线程的保护作 ...

  2. 【转载】利用jetty+Eclipse实现超轻量级web开发

    之前一直使用maven的jetty插件.今天换种方式. 使用下面介绍的方式你只有一个java project就行. 开发环境更简单,debug也更方便,不需要remote debug的方式,jetty ...

  3. MVC自学系列之三(MVC视图-Views)

    View的约定 1.根据约定,Views目录下包含着每一个与Controller同名但是没有像Controller后缀的文件夹:因此对于控制器HomeController就对应在views目录下有个目 ...

  4. windows/NBTSTAT,linux/nmblookup命令详解,查询NetBIOS名

    NBTSTAT命令详解 请问: Linux下有没有和nbtstat一样的命令,用 nmblookup -A ip 可以 nbstat命令主要用于查看当前基于netbios的tcp/ip连接状态,通过该 ...

  5. Mysql慢日志查询

    MYSQL慢查询配置: 查看是否启用慢日志查询: show VARIABLES like '%quer%'; 没有配置的情况下慢查询是关闭的:

  6. Jira在linux上安装与部署

    Where should JIRA 6.0.1 be installed? [/opt/atlassian/jira] /usr/local/jira Default location for JIR ...

  7. 【转】MFC窗口句柄各类指针获取函数

    原文网址:http://www.pythonschool.com/CPP_JHK/5003.html 获取所在类窗口的句柄 this->m_hwnd; // this是一个指针,指向当前类的实例 ...

  8. Centos 6.4 openNebula4

    我们实验室的 OpenNebula 3.2 已经很稳定的运行了两年,除了开头一个月不熟悉这套云计算软件有点乱.容易犯错外接下来的时间里都很稳定,期间还包括一次防火演习(突然拉闸似断电)和安全检查(计划 ...

  9. 爬虫技术浅析 | WooYun知识库

    爬虫技术浅析 | WooYun知识库 爬虫技术浅析 好房通ERP | 房产中介软件最高水准领导者 undefined

  10. Codeforces Round #100(140~~)

    140 A. New Year Table 题目大意:有一个大圆桌子,半径是R, 然后有n个半径是r的盘子,现在需要把这些盘子摆放在桌子上,并且只能摆放在桌子边缘,但是不能超出桌子的范围....问能放 ...