是否可以将内存映射文件包装成这样的东西?
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
请求上使用ReadMem
。 Addr
64位整数只是内存映射文件的偏移量。悬而未决的问题是如何分配这些地址 - 我目前保留了我维护的免费块列表。
答案 0 :(得分:2)
你的建议“在内部它有一个内存映射文件的句柄并在每个ReadMem请求上使用MapViewOfFile ”将只是浪费CPU资源,恕我直言。
值得一提的是,您的GetMem / FreeMem
要求将无法突破3/4 GB的障碍。由于所有分配的内存都将映射到内存中,直到调用FreeMem
,因此您将缺少内存空间,就像使用常规Delphi内存管理器一样。您可以做的最好的事情是依赖FastMM4
,并更改您的程序以减少其内存使用。
恕我直言,您必须更改/更新您的规格。例如,您的“更新”问题听起来就像是常规存储问题。
您想要的是为您的应用程序分配超过3/4 GB的数据。您已在我们的SynBigTable开源单元中实现了此类功能。这是纯Delphi中快速而轻巧的NoSQL解决方案。
它可以创建任何大小的文件(仅限64位),然后根据请求将每条记录的内容映射到内存中。如果可能,它将使用文件的内存映射。您可以使用TSynBigTable
方法直接实现界面:ReadMem=Get, AllocMem=Add, FreeMem=Delete
。这些ID将与您的pointer
类似,并且RawByteString
将用于代替TBytes
。
您可以使用整数ID或字符串ID访问任何数据块,甚至可以使用复杂的字段布局(在记录内部,或作为内存中的元数据 - 包括索引和快速搜索)。
或依赖于常规的嵌入式SQL数据库。例如,SQLite3非常擅长处理BLOB字段,并且能够存储大量数据。对于大多数使用过的记录,使用简单的内存缓存机制,它可能是一个强大的解决方案。