最近看了一篇内存分配器的论文,原理很简单,但是里面的数学论证还没看懂,这次先简单写一下原理和用到的API。

内存分配器是用于封装操作系统提供的底层API,给应用程序提供动态内存的。内存不断申请释放后,往往会形成内存碎片。当需要申请一段较大的内存时,当前剩余内存总量是够的,但是被当前申请的内存块隔断成一个个小隔间,内存分配器无法给出指定长度的内存。这时就只能向操作系统重新申请,或者对应用程序返回分配失败了。

图片来自这里

如上图所示,不断申请内存后,内存占用如Figure 2所示。应用程序释放部分内存后,形成Figure 3。前面的两个空闲内存块,就只能用来放小的内存对象了。即使总内存足够,也因为中间内存对象的隔断,无法分配出足够大的内存。

为了避免内存碎片增多,Mesh提出了内存页合并的想法。在现代的Linux系统上,内存页一般以4K大小分配,假设页A有碎片,页B也有碎片,但是页A和页B的碎片相对于页头的偏移刚好不重叠,那就可以将两者合成一页,腾出完整的一页来分配较大的内存。见下图:

(图来自论文)

这种合并的方法有一个问题,c/c++的应用程序可能直接存下了对象的地址,所以内存合并后,原有分配对象的地址不能变。作者用了一个巧妙的方法来解决这个问题:

1. 作者用内存文件系统创建了一个内存文件(mkstemp)

2. 通过mmap api创建一个1:1的内存映射,将第一步的文件映射为一块内存(mmap,这里需要设为MAP_SHARED, 如果设为 MAP_PRIVATE则重映射后B页内容会丢掉)

3. 假设算法发现有A和B两页内存可进行合并,则将B中存的对象用memcpy拷贝到A里去(memcpy或者普通的赋值操作)

4. 通过mmap api将B页重新映射到A页对应的文件偏移上(mmap,这里需要设为MAP_FIXED,表示新的内存映射就用这个地址开始)

这样应用程序依然可以通过原有的内存地址访问原有的内存对象,而对象实际上已经移动到新的位置了。

上面的步骤我做了个小实验验证了一下,的确可行。作者论文里提到修改页表来完成,之前纠结了很久为什么应用程序可以改页表,不是操作系统维护页表的吗?可以改页表不就可以碰物理内存了?……才知道原来mmap可以这样玩233333

Mesh内存分配器的mmap小技巧的更多相关文章

  1. arc下内存泄漏的解决小技巧

    一定要注意,我们运行app时,一定要关心内存的使用,尽量不要超过20M,即使有很多图片要显示也绝对不能超过30M.所以运行自己开发的app时多关心内存的使用是个很好的习惯. 对于性能,内存的优化,这个 ...

  2. Java内存管理的9个小技巧

    Java内存管理的9个小技巧很多人都说“Java完了,只等着衰亡吧!”,为什么呢?最简单的的例子就是Java做的系统时非常占内存!一听到这样的话,一定会有不少人站出来为Java辩护,并举出一堆的性能测 ...

  3. 关于Java内存管理的几个小技巧

    这里将介绍几则Java内存管理的小技巧,让你让你从Java入门开始告别陋习,为Java程序提速.有不少人都说"Java完了,只等着衰亡吧!",为什么呢?最简单的的例子就是Java做 ...

  4. 填坑总结:python内存泄漏排查小技巧

    摘要:最近服务遇到了内存泄漏问题,运维同学紧急呼叫解决,于是在解决问题之余也系统记录了下内存泄漏问题的常见解决思路. 本文分享自华为云社区<python内存泄漏排查小技巧>,作者:luti ...

  5. Nah Lock: 一个无锁的内存分配器

    概述 我实现了两个完全无锁的内存分配器:_nalloc 和 nalloc.  我用benchmark工具对它们进行了一组综合性测试,并比较了它们的指标值. 与libc(glibc malloc)相比, ...

  6. [转]STL的内存分配器

    题记:内存管理一直是C/C++程序的红灯区.关于内存管理的话题,大致有两类侧重点,一类是内存的正确使用,例如C++中new和delete应该成对出现,用RAII技巧管理内存资源,auto_ptr等方面 ...

  7. CoreCLR源码探索(三) GC内存分配器的内部实现

    在前一篇中我讲解了new是怎么工作的, 但是却一笔跳过了内存分配相关的部分. 在这一篇中我将详细讲解GC内存分配器的内部实现. 在看这一篇之前请必须先看完微软BOTR文档中的"Garbage ...

  8. 理解 glibc malloc:主流用户态内存分配器实现原理

    https://blog.csdn.net/maokelong95/article/details/51989081 Understanding glibc malloc 修订日志: 2017-03- ...

  9. 内存分配器 (Memory Allocator)

    对于大多数开发人员而言,系统的内存分配就是一个黑盒子,就是几个API的调用.有你就给我,没有我就想别的办法. 来UC前,我就是这样觉得的.实际深入进去时,才发现这个领域里也是百家争鸣.非常热闹.有操作 ...

随机推荐

  1. Win10安装LoadRunner11

    一.下载 地址:http://www.51testing.com/?uid-4827-action-viewspace-itemid-225451 二.安装 本来想写,结果和别人的一样就不写了:htt ...

  2. springboot测试的方法

    @RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest( classes = {App.class})@WebAppConfigurationpu ...

  3. java AQS 一:

    最近加班太多,很久没有更新博客了,周末看了下阿里大神并发的书籍,把知识点做个记录. 一:线程安全的定义 当多个线程并发访问某个类时,如果不用考虑运营环境下的调度和交替运行,且不需要额外的辅助,这里认为 ...

  4. django数据库的表已迁移的不能重新迁移的解决办法

    django.db.utils.InternalError: (1050, "Table 'tb_content' already exists") mysql数据库在迁移时数据库 ...

  5. EVE-NG简单入门介绍

    此篇文章简单的介绍下模拟器EVE-NG的使用,具体包括Dynamips设备导入与运行,IOL设备的导入与运行,QEMU设备的导入与运行,客户端软件的安装,物理网络与虚拟网络的结合等. 一.导入镜像 D ...

  6. js 遍历数组

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title> ...

  7. Linux快捷键 Linux权限

    第1章 回顾昨天内容 1.1 取出网卡ip地址 取出文件权限 1.2 awk '找谁{干啥}'  awk 'NR==2{print $4}' 1.3 系统时间 [root@oldboyedu-40-n ...

  8. Ubuntu18.04中安装vsftpd服务/ ftp上传文件提示无权限 553 Could not create file.

    1,安装 $ sudo apt-get install vsftpd 2.配置 备份并创建新的配置文件. $ sudo mv /etc/vsftpd.conf /etc/vsftpd.conf_ori ...

  9. mysql开启远程登陆(修改数据表和授权两种方法)

    一.确认防火墙没有阻止3306端口(一般服务器默认会屏蔽掉) windows防火墙例外设置方法 控制面板(右上角选择查看方式为大图标)---防火墙---高级设置---高级设置---出站规则---最右边 ...

  10. d3js可视化策略

    d3js是数据驱动图形的思路.基本可以这么理解,有什么样的图形,后面基本就有类似结构的数据.大概思路步骤如下: 一.适配数据格式 这一步主要是为第二部服务,第一步的结果作为第二部的入参. 比如,画层级 ...