مدیریت حافظه در سی شارپ (C#) به صورت عمده توسط سیستم مدیریت حافظه خودکار .NET یعنی Garbage Collector (GC) انجام می شود. GC به طور خودکار حافظه را تخصیص داده و اشیا بلااستفاده را پاکسازی می کند. در ادامه به چند نکته کلیدی در مورد مدیریت حافظه در سی شارپ می پردازیم:
تخصیص حافظه
هنگامی که یک شی جدید ایجاد می شود، حافظه برای آن شی در هیپ (Heap) تخصیص داده می شود. برای مثال:
Person person = new Person();
در اینجا، حافظه برای شی person از هیپ تخصیص داده می شود.
جمع آوری زباله (Garbage Collection)
GC به طور خودکار اشیا غیرقابل دسترس را شناسایی کرده و حافظه آن ها را آزاد می کند. این فرآیند در پس زمینه اجرا می شود و توسعه دهندگان نیازی به مدیریت دستی حافظه ندارند.
محدوده (Scope) و مدیریت منابع
برای مدیریت منابعی که نیاز به آزادسازی دارند (مثل فایل ها یا اتصالات شبکه)، از IDisposable و دستور using استفاده می شود. برای مثال:
using (FileStream fs = new FileStream("file.txt", FileMode.Open))
{
// عملیات با فایل
} // FileStream به طور خودکار پس از این بلوک آزاد میشود
مدیریت حافظه با IDisposable
کلاس هایی که منابع غیرمدیریتی (مثل فایل ها یا هندل های سیستم) استفاده می کنند، باید از IDisposable پیروی کنند تا بتوانند به طور صحیح منابع خود را آزاد کنند. برای مثال:
public class ResourceHolder : IDisposable
{ private bool disposed = false; // تابع آزادسازی منابع
public void Dispose()
{ Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// آزادسازی منابع مدیریتشده } //
آزادسازی منابع غیرمدیریتشده
disposed = true;
}
}
~ResourceHolder()
{
Dispose(false);
}
}
مثال کاربردی
فرض کنید کلاسی داریم که از یک اتصال شبکه استفاده می کند و باید پس از استفاده از آن آزاد شود:
public class NetworkResource : IDisposable
{
private bool disposed = false;
private Socket socket;
public NetworkResource(string ipAddress, int port)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(ipAddress, port);
}
public void SendData(byte[] data)
{
if (disposed)
throw new ObjectDisposedException("NetworkResource");
socket.Send(data);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// آزادسازی منابع مدیریتشده
if (socket != null)
{
socket.Close();
socket = null;
}
}
// آزادسازی منابع غیرمدیریتشده
disposed = true;
}
}
~NetworkResource()
{
Dispose(false);
}
}
استفاده از NetworkResource
using (NetworkResource networkResource = new NetworkResource("127.0.0.1", 8080))
{
byte[] data = Encoding.UTF8.GetBytes("Hello, World!");
networkResource.SendData(data);
} // شبکه به طور خودکار پس از این بلوک آزاد میشود
در این مثال، NetworkResource از اتصال شبکه استفاده می کند و با استفاده از الگوی IDisposable اطمینان حاصل می شود که منابع به درستی آزاد شوند.