内存分配的不同类型 一个Windows CE 应用程序有许多不同的内存分配方式。在内存食物链的底端是Virtualxxx 函数,它们直接保留,提交和释放(free)虚拟内存页。接下来的是堆(heap) API。堆是系统为应用程序保留的内存区域。堆有两种风味:当应用程序启动时自动默认分配的本地堆(local heap),以及能够由程序手动创建的分离堆(separate heap)。在堆API之后是静态数据,数据块是被编译器定义好的或者由程序手动创建的。最后,我们来看栈,这是程序为函数存储变量的区域。
一个Windows CE不支持的Win32 内存API是全局堆(global heap)。全局堆API包括Global­Alloc,GlobalFree和GlobalRealloc,将不会出现在Windows CE中(译者注:很奇怪,我在Windows CE 中仍然可以使用这几个API,并且工作正常,好像Microsoft并没有把它们完全去掉)。全局堆只是从Windows 3.x的Win16 时期继承而来。在Win32中,全部和本地的堆很类似,全局内存一个独特用法是,为剪贴板的数据分配内存,在Windows CE中已经被本地堆替代并加上了句柄。
在Windows CE中最小化内存使用的关键是选择与内存块使用模型相匹配的恰当的内存分配策略。我将回顾一下这些内存类型然后讲述Windows CE应用程序中的最小化内存使用策略。
虚拟内存
虚拟内存是内存类型中最基础的。系统调用虚拟内存API来为其他类型内存分配内存。包括堆和栈。虚拟内存API,包括VirtualAlloc,VirtualFree和VirtualReSize函数,这些可以直接操作应用程序虚拟内存空间的虚拟内存页面。页面可以保留,提交给物理内存,或使用这些函数释放。
分配虚拟内存
分配和保留虚拟内存是同过这个函数完成的:
LPVOID VirtualAlloc (LPVOID lpAddress, DWORD dwSize,
DWORD flAllocationType,
DWORD flProtect);
VirtualAlloc的第一个参数是要分配内存区域的地址。当你使用VirtualAlloc来提交一块以前保留的内存块的时候,lpAddress参数可以用来识别以前保留的内存块。如果这个参数是NULL,系统将会决定分配内存区域的位置,并且围绕64-KB的范围(译者注:就是前面说提及的最小内存分配尺寸)。第二个参数是dwSize,要分配或者保留的区域的大小。这个参数以字节为单位,而不是页,系统会根据这个大小一直分配到下页的边界。
flAllocationType参数指定了分配的类型,你可以指定或者合并以下标志:MEM_COMMIT,MEM_AUTO_COMMIT,MEM_RESERVE和MEM_TOP_DOWN。MEM_COMMIT标志分配程序使用的内存,MEM_RESERVE保留虚拟地址空间以便以后提交。保留的页不能存取直到调用VirtualAlloc的时候再次指定了MEM_COMMIT标志。第三个标志,MEM_TOP_DOWN,告