MapViewOfFile 冻结 Windows Mobile 6 设备

MapViewOfFile freezes the Windows Mobile 6 device

本文关键字:设备 Mobile Windows 冻结 MapViewOfFile      更新时间:2023-10-16

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

#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 Classic Emulator 将在 65529 次迭代后冻结。这是我做错了还是我应该注意的平台问题?

谢谢保罗·

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

编辑2:根据故障前的GlobalMemoryStatus,设备具有70.5MB/94.1MB可用物理内存。

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

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

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

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

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

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

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

-保罗·