2011-05-12 46 views
0

我有一个用于Windows Mobile 6 ARMV4I的Visual Studio 2008 C++项目,我正在使用内存映射文件。不幸的是,它会导致设备锁定。我可以用这个代码演示了这个问题:MapViewOfFile冻结Windows Mobile 6设备

#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 Mobile 6经典模拟器后会在我的测试65529次反复冻结。这是我做错了什么,或者是否有平台问题,我应该知道?

感谢, PaulH

编辑:增加到/ STACK:1048576,4096让我的设备被冻结前打65535次迭代。

编辑2:根据GlobalMemoryStatus就在故障发生前,设备拥有70.5MB/94.1MB空闲物理内存。

Edit3:我可以创建两个MMF并将它们加载到65500 * 256字节。但是,它们都不能单独超过65535个分配。实际上,分配大小并不重要。我可以将它减半,每个减少128字节,但我仍然在65535次迭代中失败。

编辑4:用实际文件来支持MMF似乎没有什么区别。 > 65535次迭代失败。

回答

0

我与能够访问源代码的人交谈过。事实证明,MapViewOfFile使用的内部参考计数器是USHORT。因此,在第65535次迭代中,它溢出并引起各地的仇恨和不满,最终停止系统。 因此,在内存映射文件中存在65535个打开视图的无证限制。

-PaulH

0

在Windows中,内存管理在页面。此外,分配这些页面时的粒度最小。在桌面Windows上,一个页面通常是4KiB,最小粒度通常是64KiB。如果您尝试使用尺寸小于VirtualAllocMapViewOfFile的尺寸,它将被四舍五入,您将浪费一些RAM。

我很确定在Windows Mobile上的页面大小也是4KiB - 因此对于每个256字节的MapViewOfFile,实际上它至少保留4KiB。您可以拨打GetSystemInfo来获取这些号码。

这意味着您的代码实际上保留至少 256MiB,并且如果分配粒度更高,则可能会更多。您的应用正在耗尽其地址空间。

+0

为什么你没有得到一个内存不足的例外? – 2011-05-12 16:22:10

+0

@Cory Nelson - 针对Windows Mobile的MapViewOfFile不要求您使用4KB分配粒度> 32位地址。 http://msdn.microsoft.com/en-us/library/aa914405.aspx – PaulH 2011-05-12 16:29:26

+0

好问题。我以前为Windows Mobile开发过,但从未耗尽内存。我不确定在这种情况下展示什么行为。 – 2011-05-12 16:29:38

0

根据this(见图4),只有256MB的地址空间被分配用于内存映射文件。 64K分配* 4KB = 256MB,所以你达到了极限。

+0

这是CE6。上面的图表显示了CE5具有1GB可用于MMF。 Windows Mobile 6.5基于CE5。 http://en.wikipedia.org/wiki/Windows_Mobile – PaulH 2011-05-12 17:12:20

+0

啊,你说得对。也许只有64K文件映射视图的硬限制(应该足以满足任何人)。不过,我并没有真正看到你的代码在做什么。为什么不直接映射整个事物并在视图中保留多个指针? – Luke 2011-05-13 11:45:10

+0

这就是我正在做的。 'MapViewOfFile'只是给我一个指向MMF的指针。内存由'CreateFileMapping'映射。 – PaulH 2011-05-13 13:21:16