1

static StreamWriterクラスに変数があります:

private static StreamWriter streamWriter = CreateStreamWriter(pathToFile);

アプリの実行中にこの StreamWriter を開く必要があるため、アプリでこの StreamWriter を閉じません。

このアプリを何度も起動して停止すると、メモリ リークが発生しますか? または、アプリを閉じると、オブジェクトは適切に破棄されますか?

このクラスは、ASP.NET MVC 4 と WPF アプリの両方で使用されるユーティリティ クラスです。

ご回答いただきありがとうございます。追加したコードは次のとおりです。

StreamWriter を含むクラスで:

public static void OnApplicationExit(object sender, EventArgs e)
{
    try
    {
        streamWriter.Flush();
        streamWriter.Close();
        streamWriter.Dispose();
    }
    catch { }
}

public static void OnApplicationExit()
{
    try
    {
        streamWriter.Flush();
        streamWriter.Close();
        streamWriter.Dispose();
    }
    catch { }
}

そして、ASP.NET MVC Global.Asax では:

    protected void Application_End()
    {
        Utilities.MyClass.OnApplicationExit();
    }
4

5 に答える 5

5

このアプリを何度も起動および停止すると、メモリリークが発生しますか?

いいえ。プロセスに関連付けられているすべてのリソースは、プロセスが終了すると自動的にオペレーティングシステムに返されます。これはWindowsの機能です。これは、マネージコードプロセスだけでなく、すべてのプロセスに当てはまります。

他の人が指摘しているように、データを失う可能性はありますが、カーネルオブジェクトをリークすることはありません。

アプリを閉じたときにオブジェクトは適切に破棄されていますか?

必ずしも。アプリケーションが「高速で失敗」して終了した場合、何も実行されないため、明らかにファイナライザーは実行されません。未処理の例外によってアプリケーションが終了した場合、ファイナライザーを実行するかどうかは実装によって定義されます。

さらに、レイモンドチェンがかつて指摘したように、プロセスがシャットダウンされていることがわかっているときにファイナライザーを実行することは、建物が取り壊される前に床を掃除するようなものです。それは時間と労力の無駄です。

つまり、プログラムの正確さのために実行されているファイナライザーに依存するべきではありません。

于 2013-02-24T15:22:12.807 に答える
4

アプリケーションのStreamWriter終了時にが破棄される保証はありません。場合によってはそうなりますが、それが不可能な場合もあります。

管理対象メモリを使用するため、メモリリークは発生しません。アプリケーションを閉じると、ヒープ全体が削除されます。

アプリケーションがシャットダウンされると開いているファイルハンドルが閉じられるため、リソースリークでもありません。

ただし、にStreamWriterは、破棄されない場合はフラッシュされないバッファがあります。つまり、ライターを使用して最後に書き込んだものがファイルから欠落している可能性があります。

于 2013-02-24T04:20:01.520 に答える
2

StreamwriterはIDisposableを実装します。したがって、Disposeメソッドを呼び出さないと、リソースを適切に破棄していることを保証できません。

私が見ているように、2つの基本的なオプションがあります。

  1. StreamWriterの静的インスタンスを保持しますが、アプリケーションがシャットダウンしているときにキャッチし、Streamwriter.Dispose()を呼び出してリソースを解放します。アプリがWPFアプリなのかWindowsフォームアプリなのかはわかりませんが、アプリのシャットダウン時に発生するイベントが見つかった場合は、そこでdisposeを呼び出すことができます。Application.ApplicationExitが必要なものかもしれないと思います。

  2. StreamWriterをインスタンス変数に変換し、usingステートメントを使用してインスタンス化し、IOを実行してから、すぐに破棄します。

    using(var writer = new StreamWriter())
    {
        //do your IO here
    }
    

編集:アプリがASP.Netアプリケーションであることを示しました。ASP.Netアプリケーションの場合、global.asaxのApplication_Startイベントで静的変数を作成し、global.asaxのApplication_Endイベントで静的変数を破棄できます。

于 2013-02-24T04:22:38.803 に答える
1

「このアプリを何度も起動および停止する」とは、プロセスが終了し、毎回新しいプロセスを開始することを意味しますか?プロセスが終了すると、そのすべてのメモリがOSによって再利用されるため、実際には「メモリリーク」は発生しません。

そうは言っても、シャットダウン時にリソースをクリーンアップするのは良い習慣だと思います。同じプロセス内で再起動することを決定する場合があります。そもそもリークがない場合よりも、リークを修正するのははるかに困難です。

シャットダウン時にライターをフラッシュするなど、他のことを行う必要があるとします。次に、シャットダウン時にキックオフされるある種のフックが必要になります。

于 2013-02-24T04:22:02.737 に答える
-1

using ステートメントを使用してください。これが最善の方法です。

using (var r = new StreamWriter(,,)) {

}

于 2013-02-24T04:14:13.297 に答える