2012-02-14 15 views
5

Webフレームワークでは、初めて匿名メソッドを試して、メモリ管理に問題がありました。プロジェクトの匿名メソッドメモリリーク

このメモリリーク(Delphi 2009)はどのように修正できますか?

リークメッセージはありません:

13から20バイト:Project27 $ ActRec X 1

program Project27; 

type 
    TTestProc = reference to procedure; 

    procedure CallMe(Proc: TTestProc); 
    begin 
    end; 

begin 
    CallMe(procedure begin end); 

    ReportMemoryLeaksOnShutdown := True; 
end. 

同じリークメッセージ "Project27 $ ActRec X 1" は全く表示されどのくらい多くの匿名メソッドが開始と終了の間にあるのか、私は漏れが個々の匿名プロシージャではなく、TTestProcタイプであると推測します。

program Project27; 

type 
    TTestProc = reference to procedure; 

    procedure CallMe(Proc: TTestProc); 
    begin 
    end; 

begin 

    ReportMemoryLeaksOnShutdown := True; 

    CallMe(procedure begin end); 

    CallMe(procedure var A: Integer; begin A := 42 ; end); 

end. 
+0

これは2009年に["QC78066プログラムユニットの開始...ブロックで匿名メソッドを使用するとメモリリーク"と報告されました] [](http://qc.embarcadero.com/wc/qcmain .aspx?d = 78066)。まだ修正されていません。 –

答えて

15

プロシージャまたは関数内で匿名メソッドを宣言すると、そのルーチンがスコープから外れるとクリーンアップされます。 (これはあまり単純化されていませんが、現在の議論では十分です。)問題は、DPRのメインルーチンが「範囲外」にならないということです。代わりに、Delphiコンパイラは、末尾にSystem.Haltへの隠し呼び出しを挿入します。返されることはありません。

このように書くと、メモリリークの通知が表示されます。あなたはそうのように、正常に終了ルーチン内で匿名メソッドの作成を置くことによってそれを修正することができます:

program Project27; 

type 
    TTestProc = reference to procedure; 

    procedure CallMe(Proc: TTestProc); 
    begin 
    end; 

    procedure Test; 
    begin 
    CallMe(procedure begin end); 
    end; 

begin 
    Test; 
    ReportMemoryLeaksOnShutdown := True; 
end. 
+3

実際これよりも多くのことがあります。 .dprファイルにグローバルスコープのインタフェース変数を宣言してそれに割り当てると、リークチェックが実行される前に整理されます。 Anonメソッドは明らかに特別です。 –

+1

@David:それは奇妙です。その後、バグのように聞こえます。誰かがQCレポートを提出する必要があります。 –

+0

他のユニットで書かれた関数を呼び出す以外に、.dprのbeginとendの間で何かを行うべきではありません。 .dprで直接手続きを宣言することはひどい習慣であり、悪いスタイルです。 –

10

私はあなたが.DPRファイル内のメインbegin..end.ブロックを使用しているため、これがあると思います。 begin..end.スコープ内で作成された隠しメモリ構造は、FastMM4がまだスコープ外ではないためメモリを検査するときには解放されません。

このメインbegin..end.ブロックの外側に匿名メソッドを置くとメモリリークは発生しません。

私の助言は、.dprファイルの中にいくつかのコードを入れないようにすることです。ほとんどの場合、バグです。そして、IDEはそれを好まない。独自のコードには分離した単位を使用し、.dprコンテンツは単独のままにします。 :)

+0

私はそれが非自明なコードのための最良の選択であることに同意しますが、コンソールプログラムでいくつかのアルゴリズムをテストするときは、しばしばすべてをdprに入れます。しかし、それでも私のanonmethosやインタフェースなどはすべて、(dprの)機能にとってはローカルであり、決してメインブロックにはありません。 –