内存管理与资源泄漏
在C#中,内存管理主要由垃圾回收器(GC)自动处理,但资源泄漏仍可能发生。常见原因包括:
- 未释放非托管资源:如文件句柄、数据库连接等未被显式释放。
- 事件订阅未取消:对象订阅事件后未被正确取消,导致对象无法被回收。
- 静态引用:静态变量持有对象引用,阻止GC回收。
- 循环引用 :对象间相互引用,且未实现
IDisposable模式。
解决方法:实现IDisposable模式
通过实现IDisposable接口确保资源释放。以下代码演示标准模式:
csharp
public class ResourceHolder : IDisposable
{
private bool _disposed = false;
private Stream _stream; // 示例非托管资源
// 释放托管和非托管资源
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// 释放托管资源
_stream?.Dispose();
}
// 释放非托管资源(若有)
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~ResourceHolder()
{
Dispose(false);
}
}
使用using语句简化资源管理
对于实现IDisposable的对象,优先使用using语句确保资源释放:
csharp
using (var resource = new ResourceHolder())
{
// 使用资源
} // 自动调用Dispose()
避免事件导致的内存泄漏
取消事件订阅防止对象滞留:
csharp
public class EventPublisher
{
public event EventHandler OnEvent;
}
public class EventSubscriber : IDisposable
{
private EventPublisher _publisher;
public EventSubscriber(EventPublisher publisher)
{
_publisher = publisher;
_publisher.OnEvent += HandleEvent;
}
private void HandleEvent(object sender, EventArgs e) { }
public void Dispose()
{
_publisher.OnEvent -= HandleEvent;
}
}
静态引用与循环引用处理
- 减少静态集合:避免静态集合长期持有对象引用。
- 弱引用(WeakReference):对缓存等场景使用弱引用,允许对象被回收:
csharp
private WeakReference<MyObject> _weakRef = new WeakReference<MyObject>(new MyObject());
通过以上方法可有效减少C#中的资源泄漏问题。