2

由于从数据库中检索大量数据,我的 C++ 应用程序偶尔会耗尽内存。它必须在 32 位 WinXP 机器上运行。

是否可以透明地(对于大多数现有代码)将数据对象交换到磁盘并仅按需将它们读入内存,所以我不限于32 位 Windows 为进程提供的 2GB?

我查看了VirtualAlloc地址窗口扩展,但我不确定它是否是我想要的。

我还发现了这个 SO question,提问者在其中创建了一个文件映射并希望在其中创建对象。一个答案建议使用placement new听起来对其余代码非常透明的方法。

这会阻止我的应用程序耗尽物理内存吗?我不完全确定,因为毕竟还有 32 位地址空间限制。或者这是尝试创建大量对象时会出现的另一种问题?

4

1 回答 1

1

只要您使用的是 32 位操作系统,您就无能为力。没有办法在虚拟内存中拥有超过 3GB(Windows 为 2GB)的数据,无论它是否实际换出到磁盘。

从历史上看,数据库一直使用读、写和查找来处理这个问题。因此,它们不是直接从内存中访问数据,而是使用假的(64 位)指针。数据被分成块(通常大约 4kb),并且这些块中的一些被分配在内存中。当他们想从假指针地址访问数据时,他们会检查该块是否已加载到内存中,如果是,他们会从那里访问它。如果不是,那么他们会找到一个空插槽并将其复制进去,然后返回地址。如果没有可用的插槽,则一条数据将被写回磁盘(如果已被修改),并且该插槽将被重用。

这样做的真正美妙之处在于,如果您的系统有足够的 RAM,那么操作系统将在任何时间点将超过 2GB 的数据缓存在 RAM 中,当您感觉实际上是在从磁盘读取和写入时,操作系统可能只是在内存中复制数据。当然,这需要支持超过 3GB 物理内存的 32 位操作系统,例如带有 PAE 的 Linux 或 Windows Server。

SQLite 有一个很好的自包含的 this 实现,你可以毫不费力地使用它。

如果您不希望这样做,那么您唯一的选择是使用 64 位操作系统或在任何给定时间点使用较少的数据。

于 2012-08-23T12:45:25.047 回答