3

我想在 Windows 上使用 c++ 创建一个虚拟分配器,它在硬盘上的文件上分配数据,以减少分配大对象时的物理内存使用量!..我不想将系统虚拟内存与 virtualAlloc.. . 我想在磁盘上创建一个文件并使用它来分配整个对象,然后将我需要的部分或对象移动到 RAM 中。

我尝试使用内存映射文件,但遇到了一些问题:我使用映射文件分配向量元素,但是当我烘烤删除其中任何一个时,元素的地址发生了变化,我也找不到方法来仅在需要时映射对象“在我的测试中我映射了整个文件”!

任何资源或开源项目都可以提供帮助???

4

5 回答 5

3

谷歌可以在这里提供帮助。几年前,我实现了一个使用共享内存存储的自定义 STL 分配器。相同的技术可用于实现磁盘支持的分配器。我将从查看这个 SourceForge 项目开始寻找灵感。

于 2009-07-14T12:41:14.927 回答
2

您可能会从 Boost.Interprocess 中找到灵感,它提供了对内存映射文件以及该内存上的分配器和容器的支持。

有关分配器设计的更多信息,请访问 http://www.boost.org/doc/libs/1_37_0/doc/html/interprocess/architecture.html

于 2009-07-14T13:16:19.360 回答
1

抱歉,您不了解(虚拟)内存的工作原理。一方面您说“我想制作”自定义内存分配器“但不占用内存中的大空间”,但另一方面您对“元素的地址已更改”感到惊讶。

这几乎是可以预料的。为确保(逻辑)对象的地址不会改变,您必须将该地址表示的内存提交给该对象。如果释放内存,它就可以重用,地址也是如此。如果该地址被重用,则不能将对象分页回该地址。

最终,这里的问题是地址和内存之间的联系非常非常紧密。回收内存意味着回收地址。

于 2009-07-14T13:15:53.557 回答
0

来自http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=213

POSIX 标头包括内存映射系统调用和数据结构。因为这个界面比 Windows 的界面更直观、更简单,所以我的内存映射示例基于 POSIX 库。

mmap() 系统调用:

caddr_t mmap(caddress_t map_addr, 
       size_t length, 
       int protection, 
       int flags, 
       int fd, 
       off_t offset);

让我们检查每个参数的含义。

在以下示例中,程序将命令行中传递的文件的前 4 KB 映射到其内存中,然后从中读取 int 值:

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>

 int main(int argc, char *argv[])
 {
 int fd;
 void * pregion;
 if (fd= open(argv[1], O_RDONLY) <0)
 {
 perror("failed on open");
 return –1;
 }
 /*map first 4 kilobytes of fd*/
 pregion=mmap(NULL, 4096, PROT_READ,MAP_SHARED,fd,0);
 if (pregion==(caddr_t)-1)
 {
 perror("mmap failed")
 return –1;
 }
 close(fd); //close the physical file because we don't need it
 //access mapped memory; read the first int in the mapped file
 int val= *((int*) pregion);
}

要取消映射映射区域,请使用 munmap() 函数:

int munmap(caddr_t addr, int length);

addr 是未映射区域的地址。长度指定应该取消映射多少内存(您可以取消映射先前映射区域的一部分)。以下示例取消映射先前映射文件的第一个千字节。在此调用之后,剩余的 3 KB 仍然映射到进程的 RAM:

munmap(pregion, 1024);
于 2009-07-14T12:23:47.590 回答
0

解决这个问题的最好方法可能是不返回指向大对象的常规指针。只需返回小型代理。这些代理对象实现了较大对象的完整接口。但是,这些代理对象可以处理 RAM 或磁盘中的原始数据。代理之间实现了 LRU 机制以优化 RAM 使用。调用者永远不会看到这些代理的地址发生变化,也不会得到任何指向原始数据的指针。

于 2009-07-14T13:59:33.160 回答