2

Windows Mobileアプリケーションのメモリパフォーマンスを最適化しており、Win32上のVirtualAllocWindowsCEの動作にいくつかの違いがあります。

次のテストを検討してください。

// Allocate 64k of memory
BYTE *a = (BYTE*)VirtualAlloc(0,       65536,
                              MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
// Allocate a second contiguous 64k of memory
BYTE *b = (BYTE*)VirtualAlloc(a+65536, 65536,
                              MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);

BYTE *c = a + 65528; // Set a pointer near the end of the first allocation
BOOL valid1 = !IsBadWritePtr(c, 8); // Expect TRUE
BOOL valid2 = !IsBadWritePtr(c+8, 4088); // Expect TRUE
BOOL valid3 = !IsBadWritePtr(c, 4096); // TRUE on Win32, FALSE on WinCE

コードは、「c」で始まる4096のデータを「割り当て」ます。Win32では、これは機能します。VirtualAllocのドキュメントには、それが合法であるか偶然であるかについての言及はありませんが、この動作を期待するGoogleで見つけたコードの例はたくさんあります。

Windows CE 5.0 / 5.2では、「c」でメモリブロックを使用すると、99%の場合問題はありませんが、一部の(すべてではない)Windows Mobile 6デバイスでは、ReadFileWriteFileがエラー87(パラメータ間違っている。)。ReadFileIsBadWritePtrまたは同様のものを呼び出していると想定し、これが原因でfalseを返します。2つのReadFile呼び出しを実行すると、すべてが正常に機能します。(もちろん、他のAPI呼び出しも失敗する可能性があります。)

上記を機能させるために、 VirtualAllocによって返されるメモリを拡張する方法を探しています。Windows CEで大量のメモリを予約することは、各プロセスが32MBしか取得できず、他のアイテムがロードされているため、他の問題を引き起こさずに大量のメモリを予約することはできないため、問題があります。(共有領域に大量のメモリを予約することは可能ですが、これには他の問題もあります。)

VirtualAllocに、事前に予約せずにリージョンを拡大または結合させる方法はありますか?

次の例を考えると、問題があるのではないかと思います。

HANDLE hHeap1 = HeapCreate(0, 0, 0); // Heap defaults to 192k
BYTE * a1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +96 bytes from start of heap
BYTE * b1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of a1
BYTE * c1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of b1
BYTE * d1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +4528 bytes from end of c1

HANDLE hHeap2 = HeapCreate(0, 4*1024*1024, 4*1024*1024); // 4MB Heap
BYTE * a2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +96 bytes from start of heap
BYTE * b2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of a2
BYTE * c2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of b2
BYTE * d2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of c2
4

3 に答える 3

2

いいえ、できません。

于 2009-05-25T16:16:21.407 に答える
2

私は IsBadWritePtr を信用しません。これを参照して ください 。例外を処理し、true または false を返します。しかし、一部のハードウェアでは、1 つのページへの書き込みなどの試行に対して例外が 1 回しか発生しないと聞いたことがあります。

MEM_COMMIT なしで VirtualAlloc を実行することはできないので、仮想メモリ アドレスを予約するだけです。次に、実際にメモリを使用する場合は、再度 VirtualAlloc を呼び出してコミットを行います。すでにページを予約しているので、それらを連続してコミットできるはずです。

前もって予約せずにやりたいと言っています。しかし、前もって予約することの何が問題になっていますか。予約は実際には物理メモリを使用しません。仮想アドレスの範囲を予約します。ページをコミットするときにのみ物理メモリを使用します。

于 2009-05-22T23:11:49.827 に答える
1

あ、わかりました。その場合、大きなメモリ領域について聞いたことがありますか?それは Microsoft の回避策/問題の修正だと思います。

基本的に、2 MB を超える VirtualAlloc を実行すると、仮想メモリの大きなメモリ領域に入り、32 MB の制限を超えることができます。

ここですべてがどのように機能するかについての非常に良い議論があります:
http://msdn.microsoft.com/en-us/library/ms836325.aspx

以前の製品で自分で使用しましたが、うまくいきました。

于 2009-05-24T19:35:59.890 に答える