MapViewOfFile冻结了Windows Mobile 6设备

时间:2011-05-12 15:53:28

标签: c++ windows-mobile memory-mapped-files

我有一个适用于Windows Mobile 6 ARMV4I的Visual Studio 2008 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;
}

在我的测试中,经过65529次迭代后,Windows Mobile 6 Classic Emulator将冻结。这是我正在做错的事情还是我应该注意的平台问题?

谢谢, PaulH

编辑:增加到/ STACK:1048576,4096允许我在设备冻结之前达到65535次迭代。

Edit2:根据失败前的GlobalMemoryStatus,设备有70.5MB / 94.1MB的可用物理内存。

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

Edit4:使用实际文件支持MMF似乎没有任何区别。失败> 65535次迭代。

3 个答案:

答案 0 :(得分:0)

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

我非常确定Windows Mobile上的页面大小也是4KiB - 因此对于每个256字节MapViewOfFile,它实际上必须保留至少 4KiB。您可以致电GetSystemInfo为自己获取这些号码。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我与有权访问来源的人进行了交谈。事实证明,MapViewOfFile使用的内部参考计数器是USHORT。因此,在65535次迭代中,它溢出并引起整个地方的仇恨和不满,最终停止了系统。 因此,存储器映射文件中存在未记录的65535个打开视图限制。

-PaulH