我有一个Linux C ++程序有相当大的内存要求。 大部分的内存只被less数几个类所占用,而且访问的次数也相当less。 我想将这些类从主内存移动到基于磁盘的存储,同时尽可能less地改变现有的代码。
这个想法是覆盖这些对象的new
运算符,并将它们分配到一个mmap()
内存区域。 这样,我的代码修改保持非常有限,程序的其余部分可以愉快地访问这些对象,而不知道任何改变,内核将确保我需要的对象在内存中,而其他的都在磁盘上。 我知道这是非常相似的交换如何工作,但交换分区通常太小,我的程序需要什么。
我有一些问题:
依次查看每个问题
它不是很清楚你希望通过这个实现什么。 Linux已经支持交换空间使用的内存(所以如果你的数据超过物理内存,一些将被交换到磁盘)。 您是否遇到地址空间不足的问题,或由于分页过多而缓慢运行? 使用mmap支持的商店也不会真的影响。
是的,你需要这个文件和你所在的空间一样大。 但是,您可以从小文件/ mmap开始,然后根据需要增大文件(和mmap其他页面)。 您也可以使用稀疏文件,以便在写入页面之前不使用磁盘空间。
有堆使用mmap支持的存储的管理器。 我看过Doug Lea malloc的版本,以及其他各种各样的bibop分配器。
在这种情况下,你可以只使用MAP_ANON,而根本没有文件。 但是,这又回到了第一个问题,因为这实质上是复制了系统malloc(和new)所做的事情。 事实上,在一些操作系统(Solaris?)上,这正是系统malloc所做的。 我以前见过的基于mmap的malloc主要是为了持久化存储(所以文件会在进程退出后保留下来,并在重启时重新映射)。
我可以想想你想采取的方法的一些问题,所以这不是一个答案。
我认为你最好的选择就是看你的设计,并考虑什么时候需要这些课程以及需要多长时间。 在不需要的时候构建,使用和丢弃 – 构建起来是否昂贵? 也许他们会更便宜地序列化到一些本地文件和重建(当我说序列化,我的意思不是简单的内存拷贝!)
最好的选择可能是指定你的程序需要配置最小的交换量,而不是试图用mmap()
来模拟更多的交换。 尤其是,最后一点不可能被克服 – 文件支持映射中的脏页通常优先写出。