C#内存泄漏的事例
一,使用非托管资源忘记及时Dispose
(1) 使用完非托管资源一定要Dispose或者使用using
using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
string str = "我好像不能全部覆盖源文件中的数据";
byte[] buffer = Encoding.Default.GetBytes(str);
fsWrite.Write(buffer,0,buffer.Length);//无返回值,以字节数组的形式写入数据
}
string path =@"C:\Users\fighting man\Desktop\FileStream的使用\vs快捷键.txt" ;
FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read);
//三个参数(参数1读取文件的路径,参数2对文件的做什么样的操作,参数3对文件中的数据做什么样的操作)
//FileStream 用来操作字节(不是一次性读取对内存压力小适合读大文件)
try
{
//创建FileStream类的对象(路径,对文件的操作,对文本文件数据的操作)
byte[] buffer = new byte[1024 * 1024 * 1];
int r = fsRead.Read(buffer, 0, buffer.Length);//把数据读到字节数组中,返回实际读到的有效字节数
string str = Encoding.Default.GetString(buffer, 0, r);//解码到实际读到的字节数
}
finally
{
fsRead.Close();//关闭流
fsRead.Dispose();//释放流
}
非托管资源还包括OracleConnection,套接字,com对象,操作excel对象等,使用完毕一定要手动Dispose。
(2)定义的自定义类里使用了非托管资源,需要继承接口IDisposable,实现Dispose方法,手动清理掉内部非托管资源。
public class DealData : IDisposable
{
private bool disposed = false;
private System.Timers.Timer t = new System.Timers.Timer();
private List<object> listAll;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
listAll.Clear();
//释放托管资源
}
t.Dispose();
//释放非托管资源
disposed = true;
}
}
~DealData() {
MessageBox.Show("析构函数");
}
}
二,静态引起的内存泄漏现象
(1)静态对象导致的内存堆积,程序不执行完毕,内存就不能释放
public class MySingletonClass
{
private static MySingletonClass myInstance;
private static List<IAmBig> bigObjects = new List<IAmBig>();
private MySingletonClass(){}
public static MySingletonClass MyInstance
{
get
{
if(myInstance == null)
{
myInstance = new MySingletonClass();
}
return myInstance;
}
}
public static IAmBig CreateBigObject()
{
var bigObject = new IAmBig();
bigobject.AllocateMemory(4096);
bigObjects.add(bigObject);
return bigObject;
}
}
public class IAmBig
{
}