我有一个Linux C程序具有相当大的内存要求.大多数内存仅由几个类消耗,并且很少被访问.我想将这些类从主内存移动到基于磁盘的存储,同时尽可能少地改变现有代码.
我们的想法是覆盖这些对象的new运算符,并将它们分配到mmap()的内存区域.这样我的代码修改仍然非常有限,程序的其余部分可以愉快地访问这些对象而不知道任何改变,并且内核将确保我需要的对象在内存中而其他对象在磁盘上.我知道这与交换如何工作非常相似,但是交换分区通常对于我的程序需要而言太小.
我有一些问题:
>这是一个非常糟糕的主意吗?你知道更好的事情来实现同样的目标吗?
>我是否需要预先分配最大文件大小,并且我是否需要在磁盘上分配所有这些空间?如果是这样,映射到稀疏文件有帮助吗?
>我不想编写自己的堆分配器.我可以使用现有的吗?
>当我的程序完成时,mmap的文件将被删除.这意味着我不希望任何页面被写入磁盘,除非内核实际上将它们从内存中删除.有没有类似于mmap的懒惰标志来实现这一点,还是这是自动的?
解决方法:
依次看每个问题
>这是一个非常糟糕的主意吗?你知道更好的事情来实现同样的目标吗?
你不希望通过这个来实现你的目标. Linux已经支持交换空间使用的内存(因此,如果您的数据超过物理内存,则某些内存将被交换到磁盘).您是否遇到地址空间不足或由于过度分页而运行缓慢的问题?使用mmap支持的商店也不会真正影响.
>我是否需要预先分配最大文件大小,并且我是否需要在磁盘上分配所有这些空间?如果是这样,映射到稀疏文件有帮助吗?
是的,您需要的文件与您正在进行的空间一样大.但是,您可以从一个小文件/ mmap开始,然后根据需要增大文件(和mmap其他页面).您还可以使用稀疏文件,以便在写入页面之前不使用磁盘空间.
>我不想编写自己的堆分配器.我可以使用现有的吗?
有些堆管理器使用mmap支持的存储.我已经看到了Doug Lea malloc的版本,以及各种其他的bibop分配器.
>当我的程序完成时,mmap的文件将被删除.这意味着我不希望任何页面被写入磁盘,除非内核实际上将它们从内存中删除.有没有类似于mmap的懒惰标志来实现这一点,还是这是自动的?
在这种情况下,您可以只使用MAP_ANON而根本没有文件.然而,这又回到了第一个问题,因为这基本上复制了系统malloc(和new)的功能.实际上在一些操作系统(Solaris?)上,这正是系统malloc所做的.我在过去看到基于mmap的自定义malloc的主要原因是持久存储(因此文件将在进程退出后保留,并在重新启动时重新映射).