用内存映射文件实现虚拟内存

时间:2011-11-17 15:16:14

标签: windows delphi delphi-xe memory-mapped-files virtual-memory

是否可以将内存映射文件包装成这样的东西?

TVirtualMemoryManager = class
public
  function  AllocMem (Size : Integer) : Pointer;
  procedure FreeMem (Ptr : Pointer);
end;

由于内存映射文件API函数全部取消,我不知道如何管理内存映射文件中的空闲区域。我唯一的想法是实现某种基本的内存管理(为不同的块大小维护免费列表),但我不知道它的效率如何。

编辑:我真正想要的(正如大卫向我明确表示的那样)是:

IVirtualMemory = interface
  function  ReadMem (Addr : Int64) : TBytes;
  function  AllocateMem (Data : TBytes) : Int64;
  procedure FreeMem (Addr : Int64);
end;

我需要在虚拟内存中存储连续的字节块(每个相对较小),并能够使用64位地址将它们读回内存。大多数时候访问是只读的。如果需要写入,我会使用FreeMem后跟AllocMem,因为无论如何大小都会不同。

我想要一个带有此接口的内存映射文件的包装器。在内部,它具有内存映射文件的句柄,并在每个MapViewOfFile请求上使用ReadMemAddr 64位整数只是内存映射文件的偏移量。悬而未决的问题是如何分配这些地址 - 我目前保留了我维护的免费块列表。

1 个答案:

答案 0 :(得分:2)

  1. 你的建议“在内部它有一个内存映射文件的句柄并在每个ReadMem请求上使用MapViewOfFile ”将只是浪费CPU资源,恕我直言。

  2. 值得一提的是,您的GetMem / FreeMem要求将无法突破3/4 GB的障碍。由于所有分配的内存都将映射到内存中,直到调用FreeMem,因此您将缺少内存空间,就像使用常规Delphi内存管理器一样。您可以做的最好的事情是依赖FastMM4,并更改您的程序以减少其内存使用。

  3. 恕我直言,您必须更改/更新您的规格。例如,您的“更新”问题听起来就像是常规存储问题。

  4. 您想要的是为您的应用程序分配超过3/4 GB的数据。您已在我们的SynBigTable开源单元中实现了此类功能。这是纯Delphi中快速而轻巧的NoSQL解决方案。

    它可以创建任何大小的文件(仅限64位),然后根据请求将每条记录的内容映射到内存中。如果可能,它将使用文件的内存映射。您可以使用TSynBigTable方法直接实现界面:ReadMem=Get, AllocMem=Add, FreeMem=Delete。这些ID将与您的pointer类似,并且RawByteString将用于代替TBytes

    您可以使用整数ID或字符串ID访问任何数据块,甚至可以使用复杂的字段布局(在记录内部,或作为内存中的元数据 - 包括索引和快速搜索)。

    或依赖于常规的嵌入式SQL数据库。例如,SQLite3非常擅长处理BLOB字段,并且能够存储大量数据。对于大多数使用过的记录,使用简单的内存缓存机制,它可能是一个强大的解决方案。