Rumah  >  Artikel  >  pembangunan bahagian belakang  >  C# Kebocoran Memori

C# Kebocoran Memori

王林
王林asal
2024-09-03 15:21:56405semak imbas

Kebocoran memori ialah situasi yang berlaku apabila program atau aplikasi menggunakan memori utama sistem dalam tempoh yang lama. Apabila atur cara tidak melepaskan memori yang diduduki olehnya semasa pelaksanaan, walaupun selepas ia menyelesaikan proses pelaksanaannya, maka ruang memori yang diperuntukkan ini merendahkan prestasi sistem dan boleh menjadikannya tidak bertindak balas. Dalam topik ini, kita akan belajar tentang C# Memory Leak.

Adalah menjadi tanggungjawab pemungut sampah untuk membebaskan memori yang diperuntukkan yang tidak digunakan, tetapi kami masih menghadapi masalah kebocoran memori kerana kadangkala kami merujuk objek yang tidak digunakan daripada pembolehubah yang tidak pernah keluar dari skop sepanjang hayat aplikasi.

Sintaks

Terdapat banyak cara untuk mengelakkan kebocoran memori dalam C#; kita boleh mengelakkan kebocoran memori semasa bekerja dengan sumber yang tidak terurus dengan bantuan pernyataan 'menggunakan', yang secara dalaman memanggil kaedah Dispose(). Sintaks untuk pernyataan 'menggunakan' adalah seperti berikut:

using(var  objectName = new AnyDisposableType)
{
//user code
}

Dalam pernyataan di atas, ‘var’ ialah kata kunci yang digunakan untuk menyimpan sebarang jenis data dan pengkompil boleh mengetahui jenis data ini pada masa penyusunan. 'objectName' ialah mana-mana nama yang ditentukan pengguna untuk objek. 'new' ialah kata kunci yang digunakan untuk memulakan objek dan 'AnyDisposableType' boleh menjadi mana-mana kelas seperti StreamReader, BinaryReader, SqlConnection, dll. yang objeknya boleh dilupuskan dengan bantuan pernyataan 'menggunakan'.

Bagaimana Kebocoran Memori Berfungsi dalam C#?

Untuk aplikasi .NET, kami mempunyai pengumpul sampah untuk membuang memori yang tidak digunakan, tetapi kami masih menghadapi masalah kebocoran memori. Ini tidak bermakna pemungut sampah tidak berfungsi dengan betul, tetapi ini berlaku kerana kejahilan oleh pengaturcara.

Andaikan kita mengabaikan kebocoran memori dalam aplikasi kita untuk tempoh yang sangat lama. Dalam kes itu, kami meningkatkan penggunaan memori aplikasi kami, yang merendahkan prestasi aplikasi kami dan boleh memusnahkannya secara beransur-ansur, memberikan OutOfMemoryException.

Terdapat dua punca utama kebocoran memori dalam C#:

  • Punca pertama ialah mempunyai objek yang tidak digunakan yang tidak lagi diperlukan tetapi masih dirujuk oleh pembolehubah yang mempunyai skopnya sepanjang hayat aplikasi. Oleh kerana objek ini mempunyai rujukan, ia tidak akan dimusnahkan oleh pemungut sampah dan akan kekal dalam ingatan selama-lamanya dan boleh menjadi punca kebocoran ingatan. Contoh situasi ini boleh menjadi acara yang telah kami daftarkan tetapi tidak pernah dinyahdaftarkan.
  • Punca kedua ialah memperuntukkan memori untuk sumber yang tidak terurus dan kemudian tidak melepaskannya selepas digunakan. Seperti sumber terurus, sumber yang tidak terurus tidak boleh dikumpul secara automatik. Oleh itu, adalah menjadi tanggungjawab pengaturcara untuk melepaskan memori tersebut selepas digunakan.

Beberapa sebab menyebabkan kebocoran memori dalam C# adalah seperti berikut:

  • Apabila kami melanggan acara, kelas yang menerbitkan acara itu memegang rujukan kepada kelas yang melanggannya. Disebabkan ini, pemungut sampah tidak akan membuang objek kelas yang melanggan acara itu, dan pada masa yang sama, jika pengaturcara tidak menyahlanggan acara itu, maka ia akan mengakibatkan kebocoran memori.
  • Menangkap ahli kelas dalam kaedah tanpa nama boleh mengakibatkan kebocoran ingatan.
  • Kelas statik dan pembolehubah statik yang berkaitan dan apa sahaja yang dirujuk oleh pembolehubah statik ini tidak boleh dikumpul sampah dan boleh menyebabkan kebocoran memori.
  • Menggunakan fungsi caching untuk tempoh yang tidak ditentukan boleh menyebabkan kebocoran memori.
  • Jika kami mempunyai benang berjalan tanpa had yang tidak mempunyai tugas dalam aplikasi kami tetapi merujuk kepada objek, ini boleh menyebabkan kebocoran memori.
  • Pengumpul sampah tidak menguruskan sumber yang tidak terurus. Oleh itu, tidak melupuskan sumber yang tidak terurus selepas menggunakannya boleh menyebabkan kebocoran memori.

Contoh C# Memory Leak

Contoh yang berbeza dinyatakan di bawah:

Contoh #1

Contoh ini menunjukkan utas yang menunggu sendiri untuk ditamatkan dan dengan itu boleh menjadi punca kebocoran ingatan.

Kod:

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();
}
}
}

Output:

C# Kebocoran Memori

Setiap kali kita menekan 'Enter' dalam program di atas, penggunaan memorinya meningkat.

Contoh #2

Contoh menunjukkan penggunaan sumber yang tidak terurus dengan bantuan pernyataan 'menggunakan' untuk mengelakkan kebocoran ingatan.

Kod:

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();
}
}
}

Output:

C# Kebocoran Memori

C# Kebocoran Memori

Bagaimana untuk mengelakkan OutOfMemoryException dalam C#?

Beberapa perkara yang perlu diingat untuk mengelakkan OutOfMemoryException akibat kebocoran memori dalam C# adalah seperti berikut:

  • Jika kami telah melanggan acara, kami perlu menyahdaftar pengendali acara daripada acara tersebut. Kita boleh melakukan ini dengan melaksanakan IDisposable.
  • Menangkap pembolehubah tempatan dan bukannya pembolehubah kelas dalam kaedah tanpa nama boleh mengelakkan kebocoran memori.
  • Mengelakkan penggunaan pembolehubah statik yang berlebihan dalam aplikasi kami, terutamanya apabila pembolehubah ini adalah jenis rujukan, kami boleh mengelakkan situasi kebocoran memori.
  • Jika kami mempunyai fungsi caching dalam aplikasi kami, maka kami perlu mengosongkan cache dengan kerap, terutamanya jika ia tidak berguna untuk tempoh yang lama. Kami juga boleh mengehadkan saiz caching dan boleh menggunakan WeakReference untuk menyimpan objek cache.
  • Pengurusan urutan yang betul dalam aplikasi mengelakkan kebocoran memori.

Kesimpulan

Apabila aplikasi tidak mengeluarkan memori yang telah digunakan semasa pelaksanaannya, memori ini akan disekat dan tidak boleh digunakan oleh mana-mana proses lain, mengakibatkan kebocoran memori. Pengumpul sampah boleh secara automatik membuang objek terurus tetapi tidak boleh membuang objek atau sumber yang tidak diurus.

Atas ialah kandungan terperinci C# Kebocoran Memori. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:C# Auto-Implemented PropertiesArtikel seterusnya:C# Auto-Implemented Properties