線程棧 stuck:存值類型,和引用類型的引用 先進後出,鏈表形式,連續擺放 CLR(公共語言運行庫(Common Language Runtime))啟動進程,main函數為一個線程入口 進程堆heap:存引用類型 進程中的一塊區域 IL:中間語言 對象的屬性為值類型出現在堆里,方法里的值類型,由 ...
線程棧 stuck:存值類型,和引用類型的引用 先進後出,鏈表形式,連續擺放 CLR(公共語言運行庫(Common Language Runtime))啟動進程,main函數為一個線程入口
進程堆heap:存引用類型 進程中的一塊區域
IL:中間語言
對象的屬性為值類型出現在堆里,方法里的值類型,由進程調用,出現在棧里
/// <summary> /// class 引用類型 /// </summary> public class ReferenceTypeClass { private int _valueTypeField;//堆:因為對象都在堆里,對象裡面的屬性也在堆里 public ReferenceTypeClass() { _valueTypeField = 0; } public void Method() { int valueTypeLocalVariable = 0;//棧:全新的局部變數,線程棧來調用方法,然後分配記憶體 new Process();//new對象,分配在堆里 } }
裝箱拆箱(僅僅是說記憶體的拷貝動作):記憶體copy 也會浪費性能 通常都是因為object,
裝箱拆箱只能發生在父子類裡面, 因為這樣你才能轉換呀
dynamic 是引用類型的語法糖
string student = "123"; string student2 = student; Console.WriteLine(student); //123 Console.WriteLine(student2);//123 student2 = "APP"; Console.WriteLine(student);//123 Console.WriteLine(student2);//APP
string student = "大山"; string student2 = "APP";//共用 student2 = "大山"; Console.WriteLine(object.ReferenceEquals(student, student2));//true 竟然一樣 //就是同一個 享元模式 CLR記憶體分配字元串的時候,會查找相同值,有就重用了
托管資源:.Net New的類,出了作用域就訪問不到了,自動釋放了,存放在進程堆中的資源; 值類型變數,存放在進程棧中,出了作用域就是放了,
非托管資源:訪問資料庫,操作Excel,Word什麼的.
析構函數 ~Class() 見下圖
public class Class : IDisposable { public int ClassId { get; set; } public string ClassName { get; set; } ~Class() { MyLog.Log($"執行{this.GetType().Name}Dispose"); } public void Dispose() { MyLog.Log($"執行{this.GetType().Name}Dispose"); } }
主要是用來釋放非托管資源,等著GC去把非托管資源釋放掉 系統自動執行
GC.Collect();//主動GC(釋放資源) GC回收的時候,CLR一定調用析構函數
Dispose() 也是釋放非托管資源的,主動釋放,方法本身是沒有意義的,我們需要在方法裡面實現對資源的釋放
GC不會調用,而是用對象時,使用者主動調用這個方法(using),去釋放非托管資源
總結:
1.迴圈New100個對象,出了作用域,就訪問不到了,沒有引用,.Net GC就釋放了,但少New對象,創建對象需要記憶體開闢空間
2.實現Idispose() 介面的 使用Using 或調用dispose() 方法
3.操作Word或Excel 的時候 時候需要註意釋放資源
前一段時間做了一個小程式,Word批量轉PDF,運行的時候記憶體持續增加,加上釋放資源就好了,見下圖
/// <summary> /// word 操作類 /// </summary> Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application(); /// <summary> ///word 轉換成pdf /// </summary> /// <param name="sourcePath"></param> /// <param name="targetPath"></param> /// <returns></returns> public bool WordToPDF(string sourcePath, string targetPath) { bool result = false; Microsoft.Office.Interop.Word.Document _document = null; // application. try { application.Visible = false; _document = application.Documents.Open(sourcePath); _document.ExportAsFixedFormat(targetPath, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF); result = true; } catch (Exception e) { Console.WriteLine(e.Message); result = false; } finally { var doc_close = (Microsoft.Office.Interop.Word._Document)_document; if (doc_close != null) { doc_close.Close(); } else { result = false; } // _document.Close(); } return result; }
4.訪問資料庫的時候還沒看
最近在補多線程,互斥線程,線程資源共用,多線程新語法