ERROR_NOT_ENOUGH_MEMORY のトラブルシューティング
-
12-09-2019 - |
質問
私たちのアプリケーションは、ある特定のユーザーのコンピュータで失敗します。 ERROR_NOT_ENOUGH_MEMORY
(「このコマンドを処理するのに十分なストレージがありません」)。
このエラーは、私たちが使用している Delphi VCL フレームワークの深いところで発生しているようです。そのため、どの Windows API 関数が原因であるかわかりません。
記憶力に問題があるのでしょうか? への電話 GlobalMemoryStatus
次の情報が得られます。
- dwTotalPhys - 1063150000 (~1 GB)
- dwAvailPhys - 26735000 (~27 MB)
- dwAvailPage - 1489000000 (~1.4 GB)
ページング ファイルに十分な空き領域があるにもかかわらず、Windows が利用可能な物理メモリをこれほど少なくするのは奇妙に思えますが、これが正常なのかどうかを判断できるほど Windows の仮想メモリ管理については知識がありません。それは...ですか?
メモリではない場合、どのリソース制限に達しているのでしょうか? ネットで読んだ内容によると、 ERROR_NOT_ENOUGH_MEMORY
アプリケーションがいくつかの制限 (GDI オブジェクト、USER オブジェクト、ハンドルなど) に達した結果である可能性があり、メモリとは限りません。Windows が適用する制限の包括的なリストはありますか?どの制限に達しているかを確認する方法はありますか?Google で調べてみましたが、体系的な概要は見つかりませんでした。
解決 3
この事件の犯人は、 互換性のあるビットマップの作成. 。どうやら Windows は、デバイス依存のビットマップに使用できるメモリに対してシステム全体でかなり厳しい制限を課す可能性があります (例: このメーリングリストのディスカッション)、システムに十分なメモリと十分な GDI リソースがある場合でも同様です。(これらのシステム全体の制限は、Windows がデバイスに依存するビットマップをビデオ カードのメモリに割り当てる可能性があるためと思われます。)
解決策は単純に、代わりにデバイス非依存ビットマップ (DIB) を使用することです (ただし、DIB はそれほど優れたパフォーマンスを提供しない可能性があります)。 このKB記事 では、デバイスに最適な DIB 形式を選択する方法について説明します。
リソース制限のその他の候補 (他の人の回答と私自身の調査から):
他のヒント
あらゆる可能性をご確認ください。
GDI-問題では、無料の GDIView のユーティリティを使用して監視することができます。そのユーザーはインストーラなしで起動することができ、単一のファイル。
また、関係するマシン上で ProcessExplorer してインストールします。
を使用すると、マシンへのアクセスがない場合は、アプリケーションによって監視状態のスクリーンショットを作成するユーザーに尋ねます。非常にlikeley、これはあなたにいくつかのヒントを与えるだろう。
このエラーの原因として、ここに挙げたものよりも一般的なのは、仮想メモリ領域の断片化です。これは、空きメモリの合計が非常に適切であるにもかかわらず、現在割り当てられている仮想メモリ領域のさまざまなビットによって空き領域が断片化されている状況です。したがって、合計空き領域が十分であるにもかかわらず、単一の連続ブロックでメモリ要求を満たすことができない場合、メモリ不足エラーが発生する可能性があります。
私の答えは、リークGDI /メモリツールを使用して、すべてのテストをやって一歩一歩を行く、DCを作成し、それを解放し、代わりにDIBSection
のCompatibleBitmap
を使用して、同じ問題を持つ私の後半の経験から、少し遅れるかもしれないが、 、など。
最後に(LOL)私はそれを発見した。
私は、これら2つのコールの優先順位を切り替えた後、全体の問題が修正されました。
DeleteDC(hdc); //do it first (always before deleting objects)
DeleteObject(obj);