C#內存泄漏的事例
阿新 • • 發佈:2018-08-23
final ets pen 釋放 nor ron pat man string
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 { }
C#內存泄漏的事例