释放Windows堆内存而不释放内存页

3
我正在实现一个堆池工具,需要一个 pool_clear() 函数(类似于 Apache Portable Runtime 的 apr_pool_clear())。这个函数允许我们一次性释放该池中分配的所有内存,而不会将内存页释放到底层系统。Windows API 只提供 HeapFree()(多个函数调用)和 HeapDestroy()(释放内存页)。

有没有在 Windows 上实现它的方法(使用本机 API)?


“Free” 的意思是 “取消物理页面的分配”,还是 “标记为堆管理器未使用但保留物理页面的分配”?(请注意,“释放”与这两者都不同,它会释放虚拟地址空间以及物理内存。) - user541686
@Mehrdad,OP使用apr_pool_clear作为类比,这让我相信他想要将内存保留在VirtualAlloc中,但允许堆重复使用。 - Sean Cline
你不使用VirtualAlloc等等来完成这个吗? - David Heffernan
我使用HeapCreate创建堆,并使用HeapAlloc和HeapFree。我的问题是,有没有一种方法可以一次性HeapFree由HeapAlloc分配的所有内存块,而不调用HeapDestroy(我想重复使用该堆)。 - user3368561
那是你的问题。你需要更多地掌控。使用VirtualAlloc等工具。 - David Heffernan
1个回答

1

HeapCreate及其他来自Kernel32Heap*函数无法提供此类功能。它们旨在提供与C标准库相同的功能,以及一些额外的调试/诊断功能。

听起来RtlCreateHeap来自ntdll会很适合,您可以自己分配内存并指定HeapBaseInitialCommitInitialReserveCommitRoutine

这意味着您可以调用RtlDestroyHeap而不会将所有虚拟内存都返回,然后再次调用RtlCreateHeap并使用相同的HeapBase,从而在相同的虚拟内存中创建一个新堆。

很遗憾,据我所知,ntdll 中的这些入口点是未记录的大部分本地API也是如此,因此调用它存在风险。链接的文档是驱动程序使用的Ntoskrnl入口点的文档。既然您明确调用了本地API,也许您理解并接受了这种风险。无论如何,使用已经实现了此功能的库几乎肯定更安全。

如果您真的对这种事情非常认真(说实话,这让我感到害怕),您肯定会想要查看ReactOS的堆实现作为Microsoft文档的补充。


使用NTDLL并没有实际风险,尽管微软想让人们相信这种说法。 - user541686
5
使用Windows未记录的功能的实际风险是真实存在的:没有人保证该功能在将来的版本中仍然可用(并且具有相同的功能)。 - Daniel
这似乎是直接使用Windows本地API的唯一方法。这不是好消息,但我会把它作为正确答案接受。我将不得不使用VirtualAlloc、VirtualFree和自定义分配器来实现它。谢谢。 - user3368561

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接