線程棧 stuck:存值類型,和引用類型的引用 先進後出,鏈表形式,連續擺放 CLR(公共語言運行庫(Common Language Runtime))啓動進程,main函數爲一個線程入口數據庫
進程堆heap:存引用類型 進程中的一塊區域小程序
IL:中間語言app
對象的屬性爲值類型出如今堆裏,方法裏的值類型,由進程調用,出如今棧裏函數
/// <summary> /// class 引用類型 /// </summary> public class ReferenceTypeClass { private int _valueTypeField;//堆:由於對象都在堆裏,對象裏面的屬性也在堆裏 public ReferenceTypeClass() { _valueTypeField = 0; } public void Method() { int valueTypeLocalVariable = 0;//棧:全新的局部變量,線程棧來調用方法,而後分配內存 new Process();//new對象,分配在堆裏 } }
裝箱拆箱(僅僅是說內存的拷貝動做):內存copy 也會浪費性能 一般都是由於object,性能
裝箱拆箱只能發生在父子類裏面, 由於這樣你才能轉換呀this
dynamic 是引用類型的語法糖spa
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什麼的.code
析構函數 ~Class() 見下圖orm
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.訪問數據庫的時候還沒看