2

每当使用 new / malloc 时,操作系统都会创建一个新的(或重用)堆内存段,与页面大小对齐并将其返回给调用进程。所有这些分配将构成进程的虚拟内存。在 32 位计算中,任何进程最多只能扩展到 4 GB。堆分配越高,进程内存的增加率越高。尽管有很多可用的内存管理/内存池,但所有这些实用程序最终都会再次创建一个堆并有效地重用它。

另一方面,mmap(内存映射)提供了将文件可视化为内存流的能力,并使程序能够直接在文件上使用指针操作。但在这里,mmap 实际上是在进程空间中分配地址范围。因此,如果我们 mmap 一个大小为 3GB 的 3GB 文件并获取进程的 pmap,您可以看到该进程消耗的总内存 >= 3GB。

我的问题是,是否可以有一个基于文件的内存池[就像映射文件一样],但是,它并不构成进程内存空间。我想象一下像内存数据库这样的东西,它由一个文件支持,读/写速度非常快,它支持指针操作[即获取指向记录的指针并存储任何东西,就像我们使用 new / malloc 一样],它可以在磁盘上增长,而无需触及进程虚拟 4GB 限制。

可能吗 ?如果是这样,我开始工作的一些指示是什么。我不是要求一个现成的解决方案/链接,而是从概念上理解它是如何实现的。

4

2 回答 2

1

这通常是可能的,但非常复杂。如果要访问文件的不同 3Gb 段,则必须重新映射,这可能会在分散访问的情况下降低性能。指针只会变得更加难以使用,因为重新调整数据会更改数据但使地址保持不变。我看过你可能感兴趣的STXXL项目;或者它可能不会。我从来没有使用过它,所以我不能给你任何其他的建议。

于 2014-03-08T09:32:39.723 回答
0

原则上,您正在寻找的是内存支持的文件缓存。例如数据库实现中有很多这样的东西(整个数据库比机器的内存大得多,应用程序开发人员可能希望为应用程序留下一点内存)。这将涉及使用某种间接方式——索引、散列或其他方式来指示您要访问文件的哪个区域,并使用该间接方式来确定内存是在内存中还是在磁盘上。您基本上必须复制操作系统和处理器的虚拟内存处理功能,通过使用表来指示您的“虚拟堆”在物理内存中的位置,如果它不存在于物理内存中,则将其读入(如果缓存已满,删除一些 - 如果它已被写入,

但是,在当今世界,您很可能拥有一台能够进行 64 位寻址的机器,因此,将应用程序重新编译为 64 位应用程序、使用mmap或类似方式访问大内存会容易得多。在这种情况下,即使 RAM 不足,您也可以通过虚拟内存系统访问文件的内存,它负责磁盘和 RAM(物理内存)之间的所有来回映射。

于 2014-03-08T09:35:50.407 回答