VirtualAlloc 是一个页面分配函数。它是用于分配内存的低级用户空间代码函数。但是你必须明白,从 VirtualAlloc 返回的内存是对齐到页面大小的倍数。
在 32 位 Windows 上,页面大小通常为 4096 字节。在其他系统上它可能更大。
因此,当您需要整页内存时,这使得 VirtualAlloc 很有用。 VirtualAlloc 可以分配大的“页面范围”。这些页面是虚拟的,因此实际上是到底层系统 RAM 的映射,并且有一半的时间被换出到交换文件,这就是为什么它被称为 VirtualAlloc,强调虚拟。
使用 VirtualAlloc 和 VirtualAllocEx 你也可以只保留一些内存页。保留页面是在您确定它们将被使用之前保持在保留状态的范围,此时您可以提交页面,此时将分配/提交页面所需的基础资源。
使用 VirtualFree 释放您使用 VirtualAlloc 分配或保留的页面。
VirtualAlloc 和 LocalAlloc 之间的区别在于 LocalAlloc 从堆中分配,而堆是一种从更大的保留页面块分配内存块的机制。在内部,堆使用 VirtualAlloc 分配大部分内存,然后将这些页面分成更小的块,您可以将这些块视为从 malloc、getmem 和 LocalAlloc 等函数返回的缓冲区。
LocalAlloc 可以看作是 Windows 内置版本的 malloc 或 getmem。对 LocalAlloc 的调用类似于在 C++ 中调用 malloc 或在 Delphi 中调用 getmem。事实上,您可以在 Delphi 中覆盖 GetMem 并使用 LocalAlloc,您的 DElphi 应用程序可能会运行相同。
调用 LocalFree 以释放一些使用 LocalAlloc 分配的内存。在内部,这会将内存块标记为可供下一个调用者使用。
所以现在决定时主要考虑的是开销。如果您需要经常分配,那么您应该使用 LocalAlloc 或 getmem,因为提交和保留虚拟页面是一个更耗时的过程。
换句话说,请使用 getmem 或 LocalAlloc,除非您有非常特殊的理由不这样做。
在我使用 Delphi 5 与 C++ 编译器的所有测试中,Delphi 5 getmem 更快,尽管那是五年前的事了。从那时起,像hoard 这样的分配器就可以使用,它可能会更快。但是当变量如此之多时,很难说哪个更快。
但可以肯定的是,LocalAlloc、malloc 和 getmem 等所有堆函数应该比使用 VirtualAlloc 分配和释放快得多,VirtualAlloc 通常用于在内部为 LocalAlloc 和 getmem 等堆函数保留内存。
对于 Pascal 程序,首选 getmem 或 SetLength,因为它更便于移植。或者您可以将自己的包装函数写入 LocalAlloc 或任何 OS 堆函数。