我一直在优化 Windows Mobile 应用程序的内存性能,并且在 Win32和Windows CE上的VirtualAlloc 之间遇到了一些行为差异。
考虑以下测试:
// Allocate 64k of memory
BYTE *a = (BYTE*)VirtualAlloc(0, 65536,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
// Allocate a second contiguous 64k of memory
BYTE *b = (BYTE*)VirtualAlloc(a+65536, 65536,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
BYTE *c = a + 65528; // Set a pointer near the end of the first allocation
BOOL valid1 = !IsBadWritePtr(c, 8); // Expect TRUE
BOOL valid2 = !IsBadWritePtr(c+8, 4088); // Expect TRUE
BOOL valid3 = !IsBadWritePtr(c, 4096); // TRUE on Win32, FALSE on WinCE
代码“分配”从“c”开始的 4096 数据。在 Win32 上这有效。我在VirtualAlloc文档中找不到任何提及它是合法的还是巧合的,但是我通过谷歌找到了许多期望这种行为的代码示例。
在 Windows CE 5.0/5.2 上,如果我使用“c”处的内存块,在 99% 的情况下没有问题,但是在某些(不是全部)Windows Mobile 6 设备上,ReadFile和WriteFile将失败并出现错误 87(参数是不正确的。)。我假设ReadFile正在调用IsBadWritePtr或类似名称,并因此返回 false。如果我执行两个ReadFile调用,那么一切正常。(当然可能还有其他 API 调用也会失败。)
我正在寻找一种方法来扩展VirtualAlloc返回的内存,以便我可以完成上述工作。在 Windows CE 上保留大量内存是有问题的,因为每个进程仅获得 32MB,并且由于正在加载其他项目,因此不可能在不引起其他问题的情况下保留大量内存。(可以在共享区域中保留更多的内存,但这也有其他问题。)
有没有办法让VirtualAlloc扩大或合并区域而不预先保留它?
鉴于以下示例,我怀疑这可能会出现问题:
HANDLE hHeap1 = HeapCreate(0, 0, 0); // Heap defaults to 192k
BYTE * a1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +96 bytes from start of heap
BYTE * b1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of a1
BYTE * c1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of b1
BYTE * d1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +4528 bytes from end of c1
HANDLE hHeap2 = HeapCreate(0, 4*1024*1024, 4*1024*1024); // 4MB Heap
BYTE * a2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +96 bytes from start of heap
BYTE * b2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of a2
BYTE * c2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of b2
BYTE * d2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of c2