我有一个VisualStudio2008WindowsMobile 6 C++项目,在这里我使用内存映射文件。不幸的是,它会导致设备锁定。我可以演示这个代码的问题:
#include <list>
#include <algorithm>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD alloc_size = 256;
DWORD alloc_max = 16 * 1024 * 1024;
DWORD alloc_count = alloc_max / alloc_size;
HANDLE f = ::CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, alloc_max, NULL );
std::list< void* > l;
for( DWORD i = 0; i < alloc_count; ++i )
{
// device freezes after 65529 iterations
l.push_back( ::MapViewOfFile( f, FILE_MAP_READ | FILE_MAP_WRITE, 0, i * alloc_size, alloc_size ) );
}
std::for_each( l.rbegin(), l.rend(), ::UnmapViewOfFile );
::CloseHandle( f );
return 0;
}
Windows 6经典模拟器将在我的测试中经过65529次迭代后冻结。这是我做错了什么,还是我应该注意到平台问题?
谢谢,PaulH
编辑:增加到/STACK:1048576,4096允许我在设备冻结前达到65535次迭代。
Edit2:根据GlobalMemoryStatus
故障前,设备有70.5MB / 94.1MB的空闲物理内存。
Edit3:我可以创建两个MMF并加载到65500 *256个字节。但是,它们都不能单独超过65535次拨款。实际上,分配的尺寸并不重要。我可以将其减半到128个字节,但仍然失败在>65535次迭代中。
Edit4:用实际文件支持MMF的似乎没有什么区别。>65535次迭代失败。
发布于 2011-05-13 17:47:02
我和一个能接触到消息来源的人谈过。事实证明,MapViewOfFile
使用的是一个内部引用计数器,即USHORT
。因此,在第65535次迭代中,它泛滥,引起了各地的仇恨和不满,最终使系统停止运行。因此,在内存映射文件中有65535个打开视图的无文档限制。
-PaulH
发布于 2011-05-12 16:19:23
在Windows中,内存在pages中进行管理。此外,在分配这些页面时有一个最小粒度。在桌面Windows上,页面通常是4KiB,最小粒度通常是64 4KiB。如果您尝试使用小于该大小的VirtualAlloc
或MapViewOfFile
,它将被舍入,您将浪费一些内存。
我确信Windows上的页面大小也将是4 4KiB,因此对于每256个字节的MapViewOfFile
,它实际上必须至少保留4个4KiB。您可以打电话给GetSystemInfo
为自己获取这些号码。
这意味着您的代码实际上保留了至少256 the,如果分配粒度更高,则可能更多。您的应用程序正在耗尽其地址空间。
发布于 2011-05-12 16:58:33
根据这 (参见图4),分配给内存映射文件使用的地址空间只有256 of。64K分配* 4KB =256 so,因此您达到了极限。
https://stackoverflow.com/questions/5980809
复制相似问题