メモリ リークは、プログラムまたはアプリケーションがシステムのプライマリ メモリを長期間にわたって使用するときに発生する状況です。プログラムが実行プロセスを完了した後でも、実行中に占有されていたメモリを解放しない場合、この割り当てられたメモリ領域によってシステムのパフォーマンスが低下し、応答しなくなる可能性があります。このトピックでは、C# のメモリ リークについて学習します。
未使用の割り当てられたメモリを解放するのはガベージ コレクタの責任ですが、アプリケーションの存続期間を通じてスコープ外に出ることのない変数から未使用のオブジェクトを参照することがあるため、依然としてメモリ リークの問題が発生します。
構文
C# ではメモリ リークを回避する方法がたくさんあります。内部的に Dispose() メソッドを呼び出す「using」ステートメントを使用すると、アンマネージ リソースを操作する際のメモリ リークを回避できます。 「using」ステートメントの構文は次のとおりです:
using(var objectName = new AnyDisposableType) { //user code }
上記のステートメントでは、「var」はあらゆるタイプのデータを格納するために使用されるキーワードであり、コンパイラーはコンパイル時にこのデータタイプを認識できます。 「objectName」は、オブジェクトのユーザー定義の名前です。 「new」はオブジェクトの初期化に使用されるキーワードで、「AnyDisposableType」は StreamReader、BinaryReader、SqlConnection などのクラスで、そのオブジェクトは「using」ステートメントを使用して破棄できます。
.NET アプリケーションの場合、未使用のメモリを処分するガベージ コレクターがありますが、それでもメモリ リークの問題が発生します。これはガベージ コレクターが適切に動作しないことを意味するのではなく、プログラマの無知が原因で発生します。
アプリケーションのメモリ リークを非常に長期間無視するとします。その場合、アプリケーションのメモリ消費量が増加し、アプリケーションのパフォーマンスが低下し、徐々にアプリケーションが破壊され、OutOfMemoryException が発生する可能性があります。
C# でのメモリ リークの主な原因は 2 つあります。
C# でメモリ リークが発生する理由は次のとおりです。
さまざまな例を以下に示します:
この例は、スレッド自体が終了するのを待機しているため、メモリ リークの原因となる可能性があることを示しています。
コード:
using System; using System.Threading; namespace ConsoleApp4 { public class Program { public static void Main() { while (true) { Console.WriteLine("Press enter key to start new thread"); Console.ReadLine(); Thread thread = new Thread(new ThreadStart(StartThread)); thread.Start(); } } public static void StartThread() { Console.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " started"); //Wait until current thread terminates Thread.CurrentThread.Join(); } } }
出力:
上記のプログラムで「Enter」を押すたびに、メモリ使用量が増加します。
メモリ リークを回避するための「using」ステートメントを使用したアンマネージ リソースの使用を示す例。
コード:
using System; using System.IO; namespace ConsoleApp4 { public class Program { public static void Main() { string filePath = @"E:\Content\memoryLeak.txt"; string content = string.Empty; try { //writing file using StreamWriter //making use of 'using' statement to dispose object after using it using (StreamWriter writer = new StreamWriter(filePath)) { writer.WriteLine("Learning C# programming"); } //reading file using StreamReader using (StreamReader streamReader = new StreamReader(filePath)) { content = streamReader.ReadToEnd(); } } catch (Exception exception) { Console.WriteLine(exception.Message); Console.ReadLine(); } Console.WriteLine(content); Console.ReadLine(); } } }
出力:
C# でのメモリ リークによる OutOfMemoryException を回避するために留意すべき点は次のとおりです。
アプリケーションが実行中に使用したメモリを解放しないと、このメモリはブロックされ、他のプロセスで使用できなくなり、メモリ リークが発生します。ガベージ コレクターは管理対象オブジェクトを自動的に破棄できますが、管理対象外のオブジェクトやリソースは破棄できません。
以上がC# メモリ リークの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。