首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows上的连续VirtualAlloc行为

Windows上的连续VirtualAlloc行为
EN

Stack Overflow用户
提问于 2009-05-17 15:23:40
回答 3查看 2.2K关注 0票数 2

我一直在优化Windows应用程序上的内存性能,并在、VirtualAlloc、论Win32Windows CE之间遇到了一些行为上的差异。

考虑以下测试:

代码语言:javascript
复制
// 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文档中都找不到任何提及,但我在谷歌上发现了许多代码示例,它们都期望出现这种行为。

在WindowsCE5.0/5.2上,如果我在"c“处使用内存块,在99%的情况下不存在问题,但是在某些(并非所有) Windows 6设备上,ReadFile & WriteFile将出现错误87 (参数不正确)。我假设IsBadWritePtr或类似的ReadFile正在调用,并因此返回false。如果我执行两个ReadFile调用,那么一切都正常。(当然还有其他API调用也会失败。)

我正在寻找一种方法来扩展VirtualAlloc返回的内存,这样我就可以完成上面的工作。在Windows上保留大量内存是有问题的,因为每个进程只有32 it,而且由于加载了其他项,因此不可能在不引起其他问题的情况下保留大量内存。(可以在共享区域中保留更大的内存,但这还存在其他问题。)

是否有办法使VirtualAlloc扩大或合并区域而不预先保留它?

鉴于以下例子,我怀疑这可能会有问题:

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-05-25 16:16:21

不,这不可能。

票数 2
EN

Stack Overflow用户

发布于 2009-05-22 23:11:49

我不相信IsBadWritePtr,看到这个:我认为它做了一些类似于试图写入内存的事情,并查看它是否得到了硬件异常。它处理异常,然后返回true或false。但是,我听说一些硬件只会在尝试写入一个页面或类似的东西时引发一次例外。

您不可能在没有VirtualAlloc的情况下使用MEM_COMMIT,所以只需保留虚拟内存地址。然后,当您实际想要使用内存时,再次调用VirtualAlloc来执行提交。因为您已经保留了页面,所以您应该能够连续地提交它们。

你说你不想预先预约就做这事。但是,提前预约有什么不对。保留实际上不使用任何物理内存,它保留了一系列虚拟地址,只有在提交页面时才会使用物理内存。

票数 2
EN

Stack Overflow用户

发布于 2009-05-24 19:35:59

啊,好吧。在这种情况下,您是否听说过大型内存区域,我认为这是Microsoft解决问题的方法/修复方法。

基本上,如果VirtualAlloc超过2 meg,它就进入虚拟内存的大内存区域,这允许您超过32 it的限制。

这里很好地讨论了这一切是如何工作的:

http://msdn.microsoft.com/en-us/library/ms836325.aspx

我自己用在以前的产品上,它帮了我的忙。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/874824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档