7

科学的なシミュレーションを行うデルファイアプリケーションを構築しています。複雑さが増しており、現在は多くのユニットとフォームで構成されています。

実行するたびにEOutOFMemoryエラーが発生し始めています。関数内で一時的にバリアントの配列を使用している間、または使用した直後に発生するようです。本当にばかげた質問をするリスクがありますが、「バリアントの配列」は問題を求めていますか?(私はすべてを文字列に変換することができましたが、バリアントの配列は原則として多くの厄介なものを節約します)。

問題のあるアレイの使用は次のようになります。

 Function  TProject.GetCurrentProjParamsAsArray(LProjectName, LProjectType : ShortString): ArrayOfVariant;
Var
  ArrayIndex : Word;
begin
    SetLength (Result,54);
    ArrayIndex := 0;
    Result [ArrayIndex] := LProjectName;        Inc(ArrayIndex);
    Result [ArrayIndex] := LProjectType;        Inc(ArrayIndex);                   // this structure makes it easier to add extra fields in the DB than hard coding the array index!!
    Result [ArrayIndex] := FileTool.DateTimeForFileNames    ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  SiteName            ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  PostCode            ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  MetFileNamePath     ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  SiteLat             ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  SiteLong            ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  SiteAlt             ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  TZoneIndex          ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  TZoneHours          ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  TZoneMeridian       ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  Albedo              ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  ArrayTilt           ;    Inc(ArrayIndex);
    Result [ArrayIndex] := SiteAndMet.  ArrayAzimuth        ;    Inc(ArrayIndex);

タスクマネージャーの場合-ピークメモリ使用量は42MB、VMは31Mで、実行ごとに最大90,000ページフォールトが発生します。(3GBのRAMを搭載したXPマシン上)

アプリケーション内のさまざまなコンポーネントによるメモリ使用量を監視するための一般的なヒントはありますか?またはこのエラーの原因を追跡しますか?

最近、メインプロジェクトデータをCSVとして保存することから、ADO DBを使用するようになりました。同時に、文字列とシングル/ダブルを常に変換するのではなく、Variantデータ型を使用するようになりました。

私は、実際にApplication.CreateForm(TProject、Project);を削除したような、さまざまなメモリ節約のヒントに従いました。.dprからのステートメントそしてそれらを動的に作成します。(とにかくフォームがほとんどの時間使用されている場合を除く)。一般的に、私は最小の実用的なデータ型(バイト、ショートストリングなど)を使用し、「パブリック」変数と関数の使用を最小限に抑えます

どんなヒントも大歓迎です、ブライアン

4

6 に答える 6

12

EOutOfMemoryメモリマネージャが特定の割り当て要求に対して連続するメモリブロックを見つけることができない場合に発生します。つまり、1)予想よりも多くのメモリを割り当てるか、2)割り当てに成功したメモリをリークするか、3)メモリをフラグメント化する(必ずしもリークする必要はない)ため、メモリマネージャは時間の経過とともにますます多くのメモリを割り当て続ける必要があります。

例外が発生した場合は、呼び出しスタックを確認してください。これにより、メモリの割り当てに失敗しているコードが表示されます。コールスタックを取得するには、デバッガーでアプリを実行するか、MadExcept、EurekaLog、JCLExceptなどの例外ロギングフレームワークを使用します。

于 2012-04-05T16:15:59.687 に答える
3

あなたが示しているコードが問題の原因であるとは思えません。おそらく症状が出る場所です。

実際に、基本的な低レベルの破損があると思われる場合は、FastMMのフルデバッグモードをオンにしてみてください。たとえば、発生しているような問題は、実際にメモリが不足するのではなく、一般的なメモリヒープの破損が原因である可能性があります。

ヒープの破損がなく、代わりに真のメモリ不足の問題がある場合、それを見つけて解決するには、通常、AQTimeなどのプロファイラーと呼ばれる適切なツールが必要です。おそらく、コードをデバッグするだけで理解できる方法で割り当てコードが間違っていて、どこかで、メモリ割り当て関数の1つまたは一連の呼び出しで、不当な量のメモリを取得しようとしていることがわかります。

ただし、nexus Quality SuiteやAQTimeなどのプロファイラー、または他の同様のツールがないと、ほとんど目が見えなくなります。アプリケーションが単に失敗し、ヒープ管理コードがメモリ不足を報告しています。ヒープを破壊している何かをどこかで行っている可能性があります。32ビットプロセスに実際に割り当てすぎているメモリが多すぎる可能性があります。コンピュータに十分な実メモリまたは仮想メモリがないか、アプリケーション内で、実現していない巨大なデータ構造を割り当てている可能性があります。

于 2012-04-05T17:59:16.560 に答える
2

FastMemメモリマネージャのフルバージョンをインストールしましたか?これは、メモリ処理のエラーを追跡するのに役立ちます。何かを漏らしていないか確認してください。

リークがない場合は、非常に極端な断片化の問題があります。オブジェクトの割り当て/割り当て解除を続けるのではなく、オブジェクトのプールを維持することで対処する必要があります。

于 2012-04-05T17:34:18.850 に答える
2

OutOfMemory例外の原因を見つけるには、例外が発生した場所だけでなく、すべてのオブジェクトの作成を調べる必要があります。

EurekaLogのようなサードパーティツールは、アプリケーションでインスタンス化され、正しく破棄されていないすべてのオブジェクトを表示できます。FreeAndNilプロシージャでtryfinallyブロックを使用して、それらを修正することができます。

于 2012-04-05T17:48:40.747 に答える
2

メモリリークのように聞こえます。

私はいつも追加します

  {$IFDEF DEBUG}
    ReportMemoryLeaksOnShutdown := DebugHook <> 0;
  {$ENDIF}

デバッグビルドのプロジェクトソースファイルに追加します。

これは、私がプログラムをどれだけうまく構築したかを示す良い指標になります。

于 2012-04-06T11:54:08.597 に答える
0

プログラムをデバッグできるようにするには、「デバッグ」セクションの説明に従ってプロジェクトオプションを設定する必要があります。
これを行ったら、プログラムを再構築し、次にエラーが発生したときに、ステップインしてコードを検査できるようになります。ウォッチ(Ctrl + Alt + W)を使用すると、割り当てたメモリの量と場所を確認できるはずです。

于 2020-03-13T15:49:44.860 に答える