2

リソースリークとは、Streams、StreamWriter(ファイル記述子を消費していると思います)、Handles(GDIまたはユーザーもグラフィックフォント)を意味します。間もなく、すべてのClosableオブジェクトがリソースとしてカウントされます。アプリケーションにリソースリークがある場合。一部のInputStreamが閉じられていないとします。ガベージコレクターがそれらをメモリから削除しないため、メモリリークが発生する可能性もありますか?

別の質問:リソースリークはパフォーマンスに影響を与えていますか?

4

5 に答える 5

3

アプリケーションにリソースリークがある場合。一部のInputStreamが閉じられていないとします。ガベージコレクターがそれらをメモリから削除しないため、メモリリークが発生する可能性もありますか?

GCは、リソースが閉じているかどうかに関係なく、リソースをクリーンアップします。シャットダウンしないとクリーンアップできないリソースはスレッドだけです。

ストリームが閉じずに破棄されると、コレクションのファイナライザーによって閉じられます。これには2つの問題があります

  • 正確に、またはこれが予測できない状況で発生した場合でも、ファイルがフラッシュされないか、ファイルが削除されないようにロックが保持されている可能性があります。
  • ファイナライザーはシングルスレッドであり、リソースを閉じるには時間がかかる場合があります。これらが十分にある場合、ファイナライザーは追いつかず、クリーンアップを待機しているリソースが多数あるため、OutOfMemoryErrorが発生します。

リソースを使い終わったら、リソースをクリーンアップすることをお勧めします。

別の質問:リソースリークはパフォーマンスに影響を与えていますか?

彼らはそうすることができます、それはどれだけ漏れているかに依存します。あなたが多くの考えを持っていないならば、あなたがそれがそうではないと確信していない限り、あなたはそれを問題とみなさなければなりません。たとえば、プログラムが1日1回24バイトのオブジェクトをリークしたり、1秒あたり100MBをリークしたりする可能性があります。すべてのリークが同じというわけではありません。

于 2012-08-09T09:18:47.863 に答える
1

Memory leak、定義上、役に立たないが、それでもあなたのプロセススペースに割り当てられているメモリです。CLR32ビットマシンでのプロセスには約1.2GBのメモリが含まれている可能性があることを考えると、アプリケーションでメモリリークが発生することは非常に危険です。

当然のことながら、すべては、アプリケーションがどれだけ大きく、ミッションクリティカルであるか+その他の要因に依存します。ただし、いずれの場合も、特にそれらが存在することをすでに知っている場合、および特にそれらがどこにあるかをすでに知っている場合は、常にそれらを避けるようにしてください。

編集

リソースリークは実際には同じ話です。リソースはメモリを割り当てるため、そのリークにより、定義上、メモリリークが発生します。

お役に立てれば。

于 2012-08-09T08:48:25.687 に答える
1

それはあなたがパフォーマンスと呼ぶものに依存します。全体的なパフォーマンスについて話していると仮定します。つまり、メモリ消費量や速度などがすべて重要です。

使用するリソースにも依存します。一部のリソース(ファイルハンドルなど)はプロセスの終了時に回復されるため、リークは実行時にのみ問題になります。その他(サーバー接続やデータベース接続など)は、アプリケーションの実行後もリークが続く可能性があります。その他(ミューテックスなど)は、できるだけ早くリリースする必要があります。

現在、結果はリソースによって異なります。リソースが同じプロセスのネイティブオブジェクトである場合、リソースをリークすると、関連するメモリがリークする可能性があります。リソースがロックしたがロック解除に失敗したミューテックスである場合は、アプリケーションをデッドロックしようとしている可能性があります。リソースが接続の場合、サーバーは、使用を停止した後もその接続を開いたままにします。リソースがファイルの場合、他のアプリケーション(または独自のアプリケーション)が再度アクセスするのを停止する可能性があります。

結局、一部のリソースはリークされる可能性がありますが、他のリソースはリークされるべきではありません。私に関する限り、リソースが漏洩することはありませんが、YMMVです。

したがって、そのリソースの重要性が認識されているかどうかに関係なく、取得したリソース(メモリ、ファイル、接続、ミューテックスなど)を常に正しく解放する習慣を身に付ける必要があります。そうすることで、正しいコーディングパターン(および考え方)を身に付けることができます。

RAII例外安全性は、概念を探求したい場合に検索するキーワードです。

C#の場合、Disposeパターン(IDisposableインターフェイスとファイナライザー)とusingキーワードが必要になります。別の解決策は、 /のfinallyクラスを使用してリソースを解放することですが、これを正しく維持することは困難です。tryfinally

Javaでは、Java 7(IIRC)が必要であり、AutoCloseableインターフェースと「try-with-resources」ステートメントを使用します。C#の場合と同様に、 /のfinallyクラスを使用してリソースを解放できますが、同じ問題があります。tryfinally

于 2012-08-09T09:12:42.813 に答える
0

はい、メモリリークは、アプリがガベージコレクターをより頻繁に実行する必要があり、実行ごとに回復できるメモリが少ないことを意味します。メモリが使い果たされると、アプリケーションがクラッシュします。

ファイルが閉じられないと、開いているファイルの最大数に達したときにアプリがファイルまたはソケットに関連することを実行できなくなり、通常、アプリケーションが使用できなくなります。

于 2012-08-09T08:48:18.300 に答える
0

未使用のオブジェクトへのルート化された参照を保持すると、リークが発生する可能性があります。まだ到達可能であるため、GCはそれを収集できません。静的インスタンスと静的イベントにアタッチされたイベントハンドラーに特に注意してください。

使い捨てオブジェクトをそのままにしておくと、ほとんどの場合、管理されていないリソースの解放が延期され、バグが発生する可能性があります(ストリームがフラッシュされないなど)。メモリを解放するとき、ガベージコレクターはアンマネージリソースを含むオブジェクトに対してファイナライザーを呼び出します。これは、GCの仕事を減らすDisposeへの堅実な呼び出しよりも費用がかかります。それは予測不可能であり、ファイナライザーは本当に最近呼び出される可能性があります。したがって、Disposeを呼び出さないと、一時的なリソース不足につながる可能性があります(残りのファイルハンドルがないなど)。

したがって、このストリームでDisposeを呼び出さなくてもメモリリークは発生しませんが、コストがかかり予測できないため、ファイナライズに依存しないでください。さらに、Disposeはリソースを解放するだけでなく、管理対象オブジェクトを適切にクリアすることもできます(バッファリングされたストリームのフラッシュなど)。

于 2012-08-09T09:07:28.840 に答える