成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

.Net垃圾收集機制 了解算法與代齡

開發 后端 算法
組成.Net平臺一個很重要的部分----垃圾收集器(Garbage Collection),今天我們就來講講它,想想看沒有GC,.Net還能稱之為一個平臺嗎?各種語言雖然都被編譯成MSIL,但是運行時的資源回收工作卻“各自為戰”,這樣不但增加了編程難度,也會使內存管理工作變得復雜無比,更也不利于平臺移植。

垃圾收集器在本質上就是負責跟蹤所有對象被引用到的地方,關注對象不再被引用的情況,回收相應的內存。在.NET平臺中同樣如此,有效的提高.NET垃圾回收性能,能夠提高程序執行效率。

其實垃圾收集并不是伴隨Java出現的,早在1958年,圖林獎得主John發明的Lisp語言就已經提供了GC的功能,這是GC的第一次出現,是思想的一次閃光!而后,1984年Dave Ungar發明的Small talk語言第一次正式采用了GC機制。.Net的垃圾回收機制是個很大的話題,如果你沒接觸過類似C++那樣的語言,就很難理解GC是一個多么重要、令人興奮的東西:

1.提高軟件系統的內聚。

2.降低編程復雜度,使程序員不必分散精力去處理析構。

3.不妨礙設計師進行系統抽象。

4.減少由于內存運用不當產生的Bug。

5.成功的將內存管理工作從程序的編寫時,脫離至運行時,使不可預估的管理漏洞變為可預估的。

1.算法

垃圾收集器的本質,就是跟蹤所有被引用到的對象,整理對象不再被引用的對象,回收相應的內存。這聽起來類似于一種叫做“引用計數(Reference Counting)”的算法,然而這種算法需要遍歷所有對象,并維護它們的引用情況,所以效率較低些,并且在出現“環引用”時很容易造成內存泄露。所以.Net中采用了一種叫做“標記與清除(Mark Sweep)”算法來完成上述任務。“標記與清除”算法,顧名思義,這種算法有兩個本領:

“標記”本領——垃圾的識別:從應用程序的root出發,利用相互引用關系,遍歷其在Heap上動態分配的所有對象,沒有被引用的對象不被標記,即成為垃圾;存活的對象被標記,即維護成了一張“根-對象可達圖”。其實,CLR會把對象關系看做“樹圖”,無疑,了解數據結構的同學都知道,有了“樹圖”的概念,會加快遍歷對象的速度。

檢測、標記對象引用,是一件很有意思的事情,有很多方法可以做到,但是只有一種是效率最優的,.Net中是利用棧來完成的,在不斷的入棧與出棧中完成檢測:先在樹圖中選擇一個需要檢測的對象,將該對象的所有引用壓棧,如此反復直到棧變空為止。棧變空意味著已經遍歷了這個局部根(或者說是樹圖中的節點)能夠到達的所有對象。樹圖節點范圍包括局部變量(實際上局部變量會很快被回收,因為它的作用域很明顯、很好控制)、寄存器、靜態變量,這些元素都要重復這個操作。一旦完成,便逐個對象地檢查內存,沒有標記的對象變成了垃圾。

“清除”本領——回收內存:啟用Compact算法,對內存中存活的對象進行移動,修改它們的指針,使之在內存中連續,這樣空閑的內存也就連續了,這就解決了內存碎片問題,當再次為新對象分配內存時,CLR不必在充滿碎片的內存中尋找適合新對象的內存空間,所以分配速度會大大提高。

但是大對象(large object heap)除外,GC不會移動一個內存中巨無霸,因為它知道現在的CPU不便宜。通常,大對象具有很長的生存期,當一個大對象在.NET托管堆中產生時,它被分配在堆的一個特殊部分中,移動大對象所帶來的開銷超過了整理這部分堆所能提高的性能。

Compact算法除了會提高再次分配內存的速度,如果新分配的對象在堆中位置很緊湊的話,高速緩存的性能將會得到提高,因為一起分配的對象經常被一起使用(程序的局部性原理),所以為程序提供一段連續空白的內存空間是很重要的。 #p#

2.代齡(Generation)

代齡就是對Heap中的對象按照存在時間長短進行分代,最短的分在第0代,最長的分在第2代,第2代中的對象往往是比較大的。Generation的層級與FrameWork版本有關,可以通過調用GC.MaxGeneration得知。

通常,GC會優先收集那些最近分配的對象(第0代),這與操作系統經典內存換頁算法“最近最少使用”算法如出一轍。但是,這并不代表GC只收集最近分配的對象,通常,.Net GC將堆空間按對象的生存期長短分成3代:新分配的對象在第0代(0代空間最大長度通常為256K),按地址順序分配,它們通常是一些局部變量;第1代(1代空間最大長度通常為2 MB)是經過0代垃圾收集后仍然駐留在內存中的對象,它們通常是一些如表單,按鈕等對象;第2代是經歷過幾次垃圾收集后仍然駐留在內存中的對象,它們通常是一些應用程序對象。

當內存吃緊時(例如0代對象充滿),GC便被調入執行引擎——也就是CLR——開始對第0代的空間進行標記與壓縮工作、回收工作,這通常小于1毫秒。如果回收后內存依然吃緊,那么GC會繼續回收第1代(回收操作通常小于10毫秒)、第2代,當然GC有時并不是按照第0、1、2代的順序收集垃圾的,這取決于運行時的情況,或是手動調用GC.Collect(i)指定回收的代。當對第2代回收后任然無法獲得足夠的內存,那么系統就會拋出OutOfMemoryException異常,當經過幾次GC過后,0代中的某個對象仍然存在,那么它將被移動到第1代。同理,第1、2代也按同樣的邏輯運行。

這里還要說的是,GC Heap中代的數量與容量,都是可變的(這由一個“策略引擎”控制,在第二節中,會介紹到“策略引擎”), 以下代碼結合Windbg可以說明這個問題,以下代碼中,可以通過單擊按鈕“button1”,不斷的分配內存,而后獲得對象“a”的代齡情況,并且在Form加載時也會獲得“a”的代齡。

  1. public partial class Form1 : Form  
  2. {  
  3.         private string a = new string('a',1);  
  4.         public Form1()  
  5.         {  
  6.             InitializeComponent();  
  7.         }  
  8.         private void button1_Click(object sender, EventArgs e)  
  9.         {  
  10.             a = new string('a', 900000);  
  11.             label1.Text = GC.GetGeneration(a).ToString();  
  12.         }  
  13.         private void Form1_Load(object sender, EventArgs e)  
  14.         {  
  15.             label1.Text = GC.GetGeneration(a).ToString();  
  16.         }  

程序剛加載時,“a”的代齡為第0代,通過windbg我們還獲得了以下信息:

windbg信息

可以看出,GC堆被分成了兩個段,三代,每代起始地址十進制差值為12,點擊數次“button1”按鈕后,“a”的代齡升為第2代,通過windbg我們又獲得了以下信息:

windbg信息

這里要注意一個很關鍵的地方,就是各代的起始(generation x starts at)十進制地址差值不再是12,0代與1代差為98904,1代與2代差為107908,這說明代的大小隨程序運行在改變,并且GC heap的大小也有變化。

文章原標題:.Net Discovery系列之三--深入理解.Net垃圾收集機制(上)

原文鏈接:http://www.cnblogs.com/isline/archive/2009/03/03/1402350.html

【編輯推薦】

  1. 淺析提高.NET垃圾回收性能的幾種方法
  2. .Net Framework垃圾收集具體算法詳解
  3. .NET Framework回收內存操作細節披露
  4. .NET Framework 4.0功能特點詳細講解
  5. 深入.NET Framework 4.0 關于Lazy的點滴
責任編輯:王曉東 來源: 博客園
相關推薦

2024-07-15 08:00:00

2010-01-06 16:33:50

.Net Framew

2009-10-30 10:47:48

VB.NET垃圾收集器

2021-11-05 15:23:20

JVM回收算法

2009-06-15 16:14:40

Java垃圾收集算法GC

2010-03-04 14:33:11

.NET垃圾收集

2009-09-02 09:23:26

.NET內存管理機制

2024-01-15 11:12:28

Go內存開發

2024-05-28 00:00:03

Java垃圾收集機制

2010-01-14 11:28:54

JVM分代垃圾回收

2023-02-26 11:50:04

Hbase程序Oracle

2017-09-21 14:40:06

jvm算法收集器

2024-03-15 08:04:30

G1CMSJVM

2010-09-26 13:29:46

JVM垃圾回收

2011-12-26 09:50:05

.NET垃圾回收

2022-05-06 22:13:56

JVM垃圾收集算法

2017-08-04 10:53:30

回收算法JVM垃圾回收器

2020-10-26 13:42:28

Python算法垃圾

2020-05-14 13:39:19

Java 垃圾回收機制

2009-08-13 16:57:37

.NET緩存機制
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久欧洲 | 国产传媒视频在线观看 | 蜜月aⅴ免费一区二区三区 99re在线视频 | 午夜精品久久久久久久99黑人 | 在线高清免费观看视频 | 久久夜色精品国产 | 99久久久久久久 | 自拍视频精品 | www.日本国产 | 亚洲色图婷婷 | 免费看的黄网站 | 国产一区二区三区视频 | 国产精品视频一区二区三区四区国 | 美女视频h | 日韩成人av在线播放 | 91影院在线观看 | jizz18国产| 国产视频1区2区 | 日韩国产一区二区三区 | 狠狠亚洲 | 久久精品99 | 成av在线| 国产高清视频在线观看播放 | 国产午夜精品久久 | 免费大黄视频 | 亚洲视频在线免费观看 | 国产日韩免费视频 | 久久国产精品99久久久久久丝袜 | 欧美一区二区三区在线观看视频 | 成年人在线 | www.性色| 日本一区二区三区精品视频 | 午夜精品久久久久久久久久久久久 | 一区二区三区免费观看 | 中文字幕日韩欧美一区二区三区 | 自拍偷拍第一页 | 日韩精品色网 | 亚洲欧美国产精品一区二区 | 午夜在线影院 | 91亚洲国产成人久久精品网站 | 久久精品亚洲精品国产欧美 |