2009-09-21 5 views
5

ERROR_NOT_ENOUGH_MEMORY( "このコマンドを処理するのに十分な記憶域がない")という特定のユーザーのコンピュータで、アプリケーションが異常終了しています。ERROR_NOT_ENOUGH_MEMORYのトラブルシューティング

私たちが使用しているDelphi VCLフレームワークのどこかの深いところにエラーが表示されているようですが、どのWindows API関数が責任を負っているのかわかりません。

メモリに問題はありますか?GlobalMemoryStatusへの呼び出しは、以下の情報を提供します:

  • dwTotalPhys - 1063150000(約1 GB)
  • dwAvailPhys - 26735000(〜27メガバイト)
  • dwAvailPage - 14.89億(〜1.4ギガバイト)

ページングファイルで利用可能な領域が多くなると、Windowsが利用可能な物理メモリを非常に低くすることができて不思議に思われますが、これが正常かどうかを知るためのWindowsの仮想メモリ管理については十分に分かりません。それは...ですか?

メモリではない場合、どのリソース制限がヒットしていますか?私がオンラインで読んだところでは、ERROR_NOT_ENOUGH_MEMORYは、アプリケーションがいくつかの制限(GDIオブジェクト、USERオブジェクト、ハンドルなど)のいずれかに当たった結果であり、必ずしもメモリではない可能性があります。 Windowsが実施する制限の包括的なリストはありますか?どちらの制限が当たっているかを知る方法はありますか?私はGoogleを試しましたが、体系的な概要は見つかりませんでした。

+0

GDIが私の最初の呼び出しポートです。あるユーザーのマシンでしか起こっていないことは間違っていますが、それが私が始めるところです。それはまた、使用中のハンドルの数のようなものかもしれません。幸運を祈る! –

答えて

3

この場合の原因はCreateCompatibleBitmapです。どうやら、たとえシステムにたくさんのメモリとたくさんのGDIリソースがあっても、Windowsはデバイス依存のビットマップ(たとえばthis mailing list discussion参照)で使用できるメモリのシステム全体の制限をかなり厳しく制限することがあります。 (これらのシステム全体の制限は、Windowsがビデオカードのメモリにデバイス依存のビットマップを割り当てている可能性があるため)明らかに、デバイスに依存しないビットマップ(DIB)を使用するだけですパフォーマンス)。 This KB articleは、デバイスに最適なDIBフォーマットを選択する方法について説明しています。(他の人の回答と私自身の研究から)リソース制限のため

他の候補:

  • GDIリソース(この回答から) - 簡単に(この答えから)GDIView
  • 仮想メモリの断片化
  • で確認
  • デスクトップヒープ - 私の答えは少し遅れる場合がありますhereまたはhere
3

このエラーは、仮想メモリ領域が断片化されていることが原因です。これは、全空きメモリがかなり妥当である間、空き領域は、現在割り当てられている仮想メモリ空​​間の様々なビットで断片化される状況である。したがって、メモリが不足しているにもかかわらず、1つの連続したブロックでメモリ要求が満たされない場合は、メモリ不足エラーが発生する可能性があります。

+0

これは、新しく再起動して同じことを試みることによって、かなり簡単にチェックできるはずです。彼らはそれをSOの質問として掲示する前にそれを試してみたと思うだろう(しかし、何かが起こった...) –

+0

@ T.E.D。再起動は、フォールティングしているプロセスを強制終了して再試行するだけでは効果的ではありません。各プロセスは、最初に作成されるときに独自の新しい仮想メモリ空​​間を持ちます。この問題は通常、長時間実行されるアプリで自然に発生します。または、大小のメモリチャンクが混在していて、異なる生涯にわたって割り当てられたり、割り当てが解除されたりすると、すぐに問題が発生します。通常、コードの一部は、常にメモリを割り当てたり解放したりするのではなく、再利用するバッファのリストを保持しなければならないというインジケータです。 – AnthonyWJones

+0

DelphiでFastMMを使用すると、仮想メモリの断片化を防ぐことができます。 –

4

すべての可能性を確認してください。

無料のGDIViewユーティリティを使用してGDI問題を監視できます。ユーザーがインストーラーなしで起動できる単一のファイルです。

また、該当するマシンにProcessExplorerをインストールしてください。

マシンにアクセスできない場合は、アプリケーションによって監視されているステータスのスクリーンショットを作成するようユーザーに依頼してください。非常に似ている、これはあなたにいくつかのヒントを与えるでしょう。

+0

GDIViewは興味深い印象的な "the GDIオブジェクト"について詳細を提供します。 – Wolf

0

を見たが、私の後半Eからすべてのテストを行い、ステップを踏んで、DCを作成し、リリースし、CompatibleBitmapの代わりにDIBSectionを使用し、リークGDI /メモリツールなどを使用します。

最後に(LOL) :

私はこれら2つの呼び出しの優先順位を切り替えていましたが、全体の問題は修正されました。

DeleteDC(hdc);  //do it first (always before deleting objects) 
DeleteObject(obj); 
関連する問題