2011-05-12 49 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