原文地址:http://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA==&mid=206721898&idx=1&sn=dfaee0ae6fa092b1a6db5779d75c0a2d&scene=5#rd
下面是本菜鳥對上述大神文章簡單總結,當然還有許多不足之處,希望大家還是看上面鏈接中的文章較好!
一基本原理:
計算機內存大致分為兩種:棧和堆。C#中分為兩種類型:值類型和引用類型。其中值類型主要存儲在棧區(棧的機制實際通過類似鏈表實現的),引用類型實際內存分配在堆在隊中,但棧區維護了引用類型的實際地址,類似的使用值類型存儲方式,實現對指針的維護
當實例化一個引用類型的變量時會經過以下步驟:
1.計算索要實例化變量一共需要的字節數
2.計算實例化對象的額外所需的字節數(類型對象指針和同步快索引)
3.CLR檢測是否有足夠的內存
A.內存足夠就直接分配,
B.內存不夠,執行一次垃圾回收,再次檢查內存是否足夠,任然不足就拋出 OutMemeryException異常
二.檢查不再使用的對象
每個應用程序都有一組根,每個根代表著一個存儲對象(特指引用類型)
1.標記階段,遍歷所有的根,遞歸的方式,在有對象引用的根的同步塊索引上設置標記
2.壓縮階段。該階段垃圾收集器線性的遍歷堆以尋找包含未標記對象的連續 區塊。如果垃圾收集器找到了較小內存塊,那麼它忽略內存不計;如果找到 了較大的連續內存塊,那麼垃圾收集器將把內存中非垃圾對象搬移到這些連 續內存塊中以壓縮托管堆
三,代的概念
對象代(generation)的概念
0代,新創建的實例,CLR未對其做任何的檢查
1代,CLR檢查過一次,未被回收的對象
2代,CLR檢查過二次及以上,仍然未被回收
CLR在程序初始時為每一代分配一定的內存空間,當創建對象發現內存不夠,會執行一次垃圾回收機制。當0代內存夠用時,不會回收1代中不可達對象。只有0代內存超出預算時,才會清理1代中的對象,這樣一來程序僅需要標記部分對象就可以實現有效的垃圾回收機制。