2

私たちのアプリケーションでは、( mapViewOfFileを介して) 複数の (つまり、最大 4 つまでの) ファイルをメモリにマップできる必要があります。長い間、これは問題ではありませんでしたが、ここ数年でファイルがますます大きくなったため、メモリの断片化により、これらの大きなファイルをマッピングできなくなりました (ファイルは約 200 MB になります)。その時点で他のファイルがロードされていない場合、問題はすでに存在している可能性があります。

現在、マッピングが常に成功するようにする方法を探しています。そのため、プログラムの開始時にマッピング用にのみメモリのブロックを予約したかったので、断片化の影響がはるかに少なくなりました。

私の最初のアプローチは、プライベート ヒープをHeapCreateすることでした。次に、1 つのファイルのマッピングを保持するのに十分な大きさのメモリ ブロックをHeapAllocし、そのブロックのアドレスでMapViewOfFileExを使用します。当然、アドレスはメモリ割り当ての粒度と一致する必要があります。しかし、マッピングはエラー コード ERROR_INVALID_ADDRESS (487) で失敗しました。

次に、 VirtualAlocで同じことを試しました。私の理解では、パラメーター MEM_RESERVE を渡すと、ファイルのビューをマップするなど、必要に応じてそのメモリを使用できるようになります。しかし、 VirtualFreeでブロック全体を完全に解放するまで、それは不可能であることがわかりました (上記と同じエラー コード) 。そのため、次のファイル用に予約されたメモリはもうありません。

私はすでに低断片化ヒープ機能を使用していますが、ほとんど役に立ちません。ファイルの小さなビューのみを使用するようにコードを書き直すことは、現時点ではオプションではありません。この投稿も見ました障害の可能性なしに MapViewOfFileEx への複数の呼び出しのためにアドレス空間をリサイクルできますか? しかし、それが非常に役立つとは思えず、別の可能性を望んでいました。

私に何ができるか、または私のデザインがどこで間違っている可能性があるかについて何か提案はありますか? ありがとうございました。

4

1 に答える 1

0

さて、ドキュメントMapViewOfFileExは明確です:「提案されたアドレスは、ファイルが複数のプロセスで同じアドレスにマップされる必要があることを指定するために使用されます。これには、関連するすべてのプロセスでアドレス空間の領域が使用可能である必要があります。他のメモリ割り当てはできませんマッピングに使用される地域で行われますVirtualAlloc

低断片化ヒープは、比較的小さな割り当てでも失敗しないようにすることを目的としています。つまり、1 バイトの穴が回避されるため、2 バイトの割り当てがより長く可能になります。あなたの割り当ては、32ビットの標準では小さくありません。

現実的に、これは傷つくでしょう。本当に必要な場合は、メモリ マップト ファイルを再実装してください。必要な機能はすべて利用可能です。ベクトル化された例外ハンドラーを使用してソースをページインし、QueryWorkingSetページがダーティかどうかを判断するために使用します。

于 2012-04-24T22:08:17.633 に答える