4

私は新しいプログラマーで、メモリリークの問題を思いつきました。ループ内で変数を宣言して何度も宣言すると、メモリ リークが発生しますか? たとえば、私は

while(true)
{
    Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768);
    //do something else
}

無限ループであることは知っていますが、私の質問はメモリに関するものです。このループでメモリ使用量が急速に増加していますか? MyImage を手動でリリースする必要がありますか?

4

5 に答える 5

6

MyImage.Dispose()ご利用後はお電話が必要です。

別の方法は、コードを次のように変更することです。

while(true)
{
    using(Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768)){
        //do something else
    }
}
于 2012-06-11T15:42:12.073 に答える
3

最終的には、ガベージ コレクター (GC) がこの作業を行います。あなたが提案するような場合、注意が必要です。この場合、GC はガベージ コレクションとアプリケーションのメモリ消費量 (ワーキング セット) に費やす時間を管理しようとするからです。その結果、アプリケーションは、特に図のような場合に、必要以上のメモリを消費する可能性があります。

CLR はこのメモリを完全に自動的に処理し、マネージド メモリの割り当てを自分で解除することはありません。たとえば、次のことを考えてみましょう

public void Test()
{
    byte[] myArray = new Byte[1000];
    // ...
}

実行するTestと、1000 バイトを保持するための配列がメモリ ヒープに割り当てられます。配列は変数によって参照myArrayされ、ローカル変数スタックに格納されます。このメソッドが終了すると、このローカル変数はスコープから外れます。つまり、メモリ ヒープ上の配列を参照するものは何も残っていません。その後、孤立したアレイは、GC によって再利用できるようになります。ただし、収集するかどうかに関する CLR の決定は、多くの要因 (使用可能なメモリ、メモリの現在の割り当て、最後の収集からの時間など) に基づいているため、この収集はすぐには行われない場合があります。ガベージ コレクションまでの時間。

上記に照らして、説明した場合、ループ/包含メソッドの実行中にメモリ消費が大幅に増加します。usingここでは、ステートメントを使用する方がはるかに優れています

while (true)
{
    using (Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768))
    {
        // ...
    }
}

または、各ループの後dispose()にオブジェクトを呼び出します。Image

while (true)
{
    Image<Gray, Byte> MyImage = new Image<Gray, Byte> (1024, 768);
    // ...
    MyImage.Dispose();
}

余談ですが、(System.Diagnostics を使用して) パフォーマンス カウンターを照会することで、いつでもこのようなメモリ消費量を自分で確認できます (プロセスの実際のメモリ消費量をテストします)。

string procName = Process.GetCurrentProcess().ProcessName;
using (PerformanceCounter pc = new PerformanceCounter("Process", "Private Bytes", procName))
    Console.WriteLine(pc.NextValue());

注: パフォーマンス カウンターの読み取りには、管理者権限が必要です。

于 2012-06-11T16:23:30.523 に答える
1

ループ内で変数を宣言して何度も宣言すると、メモリ リークが発生しますか?

いいえ、そうではありません。他の人が言及した問題は、Image が Image オブジェクトをラップしている場合に発生する可能性があります

しかし、あなたの質問では、ループ内で変数を宣言し、反復ごとに新しい値を割り当てることは問題ではありません

于 2012-06-11T15:43:35.757 に答える
1

タイトなループが OOM の問題を引き起こす場合があります。ただし、Image実装されているため、リソースを使い終わったときにリソースを解放できるように、IDisposable必ずステートメントを介して呼び出すようにしてください。using

using (Image<Gray, Byte> MyImage = new Image<Gray, Byte>(1024, 768))
{
  //do stuff
}

管理対象オブジェクトを実装する場合は、必ずImage<T,U>実装してください。IDisposableImage<T,U>

于 2012-06-11T15:44:01.183 に答える
1

質問の一般的な形式では、メモリ自体をリークしているわけではありませんが、メモリフットプリントをGCが削減するよりも速く増やしている可能性があります(使用しているオブジェクトの正確な動作とメモリ占有によって異なります)。もしそうなら、これは多くのメモリリークのような影響をもたらします.

特定の例では、Image オブジェクトはアンマネージ リソースを保持します。これには、メモリ (またはファイル ハンドル、GDI オブジェクトなど) が含まれる場合があります。他の回答が指摘しているように、破棄しないと、それらのアンマネージド リソースは回収されません (または、ファイナライザーがある場合は、GC の 2 番目のパスで回収される可能性があります)。

于 2012-06-11T15:48:49.793 に答える