托管堆垃圾回收--CLR提供GC,
1、什么樣的物件需要垃圾回收?
托管資源+參考型別
托管資源和非托管資源:
托管的就是CLR控制的,例如:new的物件、string字串、變數等;
非托管不是CLR能控制的,例如:資料庫連接、檔案流、句柄、列印機連接等;
using(SqlConnection)--被C#封裝了用來管理那個非托管的資料庫連接資源;
只要是需要手動釋放的,都是非托管的,
2、哪些物件的記憶體,能被GC回收?
物件訪問不到了,那就可以被回收了
程式--入口--去找物件--建立物件圖--訪問不到的就是垃圾,
3、物件是如何分配在堆上?
連續分配在堆上面,每次分配就先檢查空間夠不夠,
4、什么時候執行GC?
a、new物件時--臨界點
b、GC.Collect 強制GC
c、程式退出時會GC
a="123"
a=null
GC.Collect 可以GC,但是頻繁GC是不好的,GC是全域的,
如果專案中有6個小時才運行new一次,什么時候GC? 這6個小時都不GC,可以手動GC,
5、GC的程序是怎么樣的呢?
N個物件--全部物件標記為垃圾--入口開始遍歷--訪問到的就標記可以訪問(+1)--遍歷完就清理記憶體--產生不連續記憶體--壓縮--地址移動--修改變數指向--所以會全域阻塞,
清理記憶體分2種情況:
a、無解構式,直接清理記憶體,
b、把物件轉移到一個單獨的佇列,會有個析構器執行緒專門做這個(清理慢一些)通常在解構式內部是用來做非托管資源釋放,因為CLR肯定會呼叫,可以避免使用者忘記的情況,
6、垃圾回收策略
物件分代:3代
0代:第一次分配到堆,就是0代
1代:經歷了一次GC,依然還在的
2代:經歷了兩次或以上GC,依然還在的
垃圾回收時,優先回收0代,提升效率,最多也最容易釋放,
0代不夠---找1代---1代不夠才找2代--再不夠就不夠了,,
大物件堆,沒有分代,直接都是2代,80000位元組以上就叫大物件,
大物件堆沒有分代這主要有2個原因:一是記憶體移動時如果是大物件則很耗資源;二是0代空間問題;
7、標準Dispose模式
using System; namespace MyGC { /// <summary> /// 標準Dispose模式 /// /// 解構式:被動清理 /// Dispose:主動清理 /// </summary> public class StandardDispose : IDisposable { /// <summary> /// 演示創建一個非托管資源 /// </summary> private string _unmanageResource = "未被托管的資源"; /// <summary> /// 演示創建一個托管資源 /// </summary> private string _manageResource = "托管的資源"; /// <summary> /// 是否已釋放 /// </summary> private bool _disposed = false; /// <summary> /// 實作IDisposable中的Dispose方法 /// </summary> public void Dispose() { this.Dispose(true); //必須為true GC.SuppressFinalize(this); //通知垃圾回識訓制不再呼叫終結器(析構器)(解構式) } /// <summary> /// 不是必要的,提供一個Close方法僅僅是為了更符合其他語言(如C++)的規范 /// </summary> public void Close() { this.Dispose(); } /// <summary> /// 解構式 /// 必須,以備程式員忘記了顯式呼叫Dispose方法 /// </summary> ~StandardDispose() { //必須為false this.Dispose(false); } /// <summary> /// 非密封類修飾用protected virtual /// 密封類修飾用private /// </summary> /// <param name="disposing">是否清理托管資源</param> protected virtual void Dispose(bool disposing) { if (this._disposed) //避免已經被釋放的拋例外 { return; } if (disposing) { //清理托管資源 if (this._manageResource != null) { //Dispose this._manageResource = null; } } //清理非托管資源 if (this._unmanageResource != null) { //Dispose conn.Dispose() this._unmanageResource = null; } //讓型別知道自己已經被釋放 this._disposed = true; } public void PublicMethod() { if (this._disposed) { throw new ObjectDisposedException("StandardDispose", "StandardDispose is disposed"); } } } }
此文由博主精心撰寫轉載請保留此原文鏈接:https://www.cnblogs.com/xyh9039/p/13715181.html
著作權宣告:如有雷同純屬巧合,如有侵權請及時聯系本人修改,謝謝!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/108728.html
標籤:ASP.NET
上一篇:.NET中的GC垃圾回收
下一篇:二維陣列中的查找
