解讀.net垃圾回收和CLR 4.0對(duì)垃圾回收所做的改進(jìn)之一_.Net教程

      編輯Tag賺U幣
      教程Tag:暫無Tag,歡迎添加,賺取U幣!

      推薦:解讀.net垃圾回收和CLR 4.0對(duì)垃圾回收所做的改進(jìn)之二
      A survey of garbage collection and the changes CLR 4.0 brings in Part 2 - series of what is new in CLR 4.0 接前篇Continue the previous post .net垃圾回收和CLR 4.0對(duì)垃圾回收所做的改進(jìn)之一 CLR4.0所帶來的變化仍然沒有在這篇,請(qǐng)看下篇。 內(nèi)存釋放

      A survey of garbage collection and the changes CLR 4.0 brings in - series of what is new in CLR 4.0

      導(dǎo)言Introduction

      垃圾回收(Garbage Collection)在.net中是一個(gè)很重要的機(jī)制. 本文將要談到CLR4.0對(duì)垃圾回收做了哪些改進(jìn). 為了更好地理解這些改進(jìn), 本文也要介紹垃圾回收的歷史.這樣我們對(duì)整個(gè)垃圾回收有一個(gè)大的印象. 這個(gè)大印象對(duì)于我們掌握.net架構(gòu)是有幫助的.

        Garbage Collection is an important component of .net. The post will talk about what has been improved in CLR 4.0. To understand it, I will take a survey of the history of garbage collection. This way we can have a big picture of garbage collection. This will help us master .net architecture in comprehensive manner.

      關(guān)于垃圾回收About Garbage collection
        在C++時(shí)代,我們需要自己來管理申請(qǐng)內(nèi)存和釋放內(nèi)存. 于是有了new, delete關(guān)鍵字. 還有的一些內(nèi)存申請(qǐng)和釋放函數(shù)(malloc/free). C++程序必須很好地管理自己的內(nèi)存, 不然就會(huì)造成內(nèi)存泄漏(Memory leak). 在.net時(shí)代, 微軟為開發(fā)人員提供了一個(gè)強(qiáng)有力的機(jī)制--垃圾回收. 垃圾回收機(jī)制是CLR的一部分, 我們不用操心內(nèi)存何時(shí)釋放, 我們可以花更多精力關(guān)注應(yīng)用程序的業(yè)務(wù)邏輯. CLR里面的垃圾回收機(jī)制用一定的算法判斷某些內(nèi)存程序不再使用,回收這些內(nèi)存并交給我們的程序再使用.

        In the times of C++, we need to allocate and release memory by ourselves carefully,  therefore there are new, delete keywords in C++, and fuctions(malloc/free) to allocate and release memory. C++ program has to manage its memory well, otherwise there will be memory leak. In .net, Microsoft provides a strong machanism to developers—Garbage collection. The Garbage collection is part of CLR. We do not need to worry about when to release memory. We can spend more time on buisness logic of applications. The Garbage colleciton of CLR adopts algorithms to decide which part of memory the program does not need any more, and then release these memory for further use.

      垃圾回收的功能The functionalities of Garbage collection
        用來管理托管資源和非托管資源所占用的內(nèi)存分配和釋放。In charging of the releasing and re-allocation of memory of managed and unmanaged resources.

        尋找不再使用的對(duì)象,釋放其占用的內(nèi)存, 以及釋放非托管資源所占用的內(nèi)存. Find the objects no longer needed, release the memory the objects occupied, and affranchise memory occupied by unmanaged resources.

        垃圾回收器釋放內(nèi)存之后, 出現(xiàn)了內(nèi)存碎片, 垃圾回收器移動(dòng)一些對(duì)象, 以得到整塊的內(nèi)存,同時(shí)所有的對(duì)象引用都將被調(diào)整為指向?qū)ο笮碌拇鎯?chǔ)位置。After releasing the memory no longer needed, there is memory scrap. Garbage collector shifts objects to get consecutive memory space, and then the references of objects will be adjusted according to the shifted address of objects.

      下面我們來看看CLR是如何管理托管資源的. Let’s see how CLR takes care of managed resources.

      托管堆和托管棧Managed heap and Managed stack:
      .net CLR在運(yùn)行我們的程序時(shí),在內(nèi)存中開辟了兩塊地方作不同的用處--托管棧和托管堆. 托管棧用來存放局部變量, 跟蹤程序調(diào)用與返回. 托管堆用來存放引用類型. 引用類型總是存放于托管堆. 值類型通常是放在托管棧上面的. 如果一個(gè)值類型是一個(gè)引用類型的一部分,則此值類型隨該引用類型存放于托管堆中. 哪些東西是值類型? 就是定義于System.ValueType之下的這些類型:

      bool byte char decimal double enum float int long sbyte short struct uint ulong ushort

      When .net CLR runs our program, CLR declares two ranges of memory for different purposes. Managed stack is to store local variables, and trace the call and return of routines. Managed heap is to store reference types. Usually value types was put on managed stack. If a value type is a part of a reference type, then the value type will be stored in managed heap along with the reference type. What are value types? They are the types defined in System.ValueType:

      bool byte char decimal double enum float int long sbyte short struct uint ulong ushort

      什么是引用類型呢? 只要用class, interface, delegate, object, string聲明的類型, 就是引用類型.  What are reference types? The types declared with class, interface, delegate, object, stirng, are reference types.

      我們定義一個(gè)局部變量, 其類型是引用類型. 當(dāng)我們給它賦一個(gè)值, 如下例:We declare a local variable, which is a reference type, and we assign a value to the local variable, like the following:

      private void MyMethod()
      {
         MyType  myType = new MyType();
         myType.DoSomeThing();
      }
      在此例中, myType 是局部變量, new實(shí)例化出來的對(duì)象存儲(chǔ)于托管堆, 而myType變量存儲(chǔ)于托管棧. 在托管棧的myType變量存儲(chǔ)了一個(gè)指向托管堆上new實(shí)例化出來對(duì)象的引用. CLR運(yùn)行此方法時(shí), 將托管棧指針移動(dòng), 為局部變量myType分配空間, 當(dāng)執(zhí)行new時(shí), CLR先查看托管堆是否有足夠空間, 足夠的話就只是簡(jiǎn)單地移動(dòng)下托管堆的指針, 來為MyType對(duì)象分配空間, 如果托管堆沒有足夠空間, 會(huì)引起垃圾收集器工作. CLR在分配空間之前,知道所有類型的元數(shù)據(jù),所以能知道每個(gè)類型的大小, 即占用空間的大小.

      In this sample, myType is a local variable. the object instantiated by new operation is stored in managed heap, and the myType local variable is stored in managed stack. The myType local variable on managed stack has a pointer pointing to the address of the object instantiated by new operation. When CLR executes the method, CLR moves the pointer of managed stack to allocate memory for the local variable myType. When CLR executes new operation, CLR checks first whether managed heap has enough space, if enough then do a simple action – move the pointer of managed heap to allocate space for the object of MyType. If managed heap does not have space, this triggers garbage collector to function. CLR knows all the metadata of types, and knows the size of all the types, and then knows how big space the types need.

      當(dāng)CLR完成MyMethod方法的執(zhí)行時(shí), 托管棧上的myType局部變量被立即刪除, 但是托管堆上的MyType對(duì)象卻不一定馬上刪除. 這取決于垃圾收集器的觸發(fā)條件.后面要介紹此觸發(fā)條件.When CLR finishs execution of MyMethod method, the local variable myType on managed stack is deleted immediately, but the object of MyType on managed heap may not be deleted immediately. This depends on the trigger condition of garbage collector. I will talk about the trigger condition later.

      上面我們了解了CLR如何管理托管資源. 下面我們來看垃圾收集器如何尋找不再使用的托管對(duì)象,并釋放其占用的內(nèi)存. In previous paragraphs, we learn how CLR manages managed resources. In following paragraphs, we will see how garbage collector find objects no longer needed, and release the memory.

      垃圾收集器如何尋找不再使用的托管對(duì)象,并釋放其占用的內(nèi)存How garbage collector find objects no longer needed and release memory
      前面我們了解了CLR如何管理托管棧上的對(duì)象.按照先進(jìn)后出原則即可比較容易地管理托管棧的內(nèi)存. 托管堆的管理比托管棧的管理復(fù)雜多了.下面所談都是針對(duì)托管堆的管理. In previous paragraphs, we learn how CLR manages the objects on managed stack. It is easy to manage managed stack as long as you utilize the rule “first in last out”. The management of managed heap is much more complicated than the management of managed stack. The following is all about the management of managed heap.

      根The root
      垃圾收集器尋找不再使用的托管對(duì)象時(shí), 其判斷依據(jù)是當(dāng)一個(gè)對(duì)象不再有引用指向它, 就說明此對(duì)象是可以釋放了. 一些復(fù)雜的情況下可以出現(xiàn)一個(gè)對(duì)象指向第二個(gè)對(duì)象,第二個(gè)對(duì)象指向第三個(gè)對(duì)象,…就象一個(gè)鏈表. 那么, 垃圾收集器從哪里開始查找不再使用的托管對(duì)象呢? 以剛才所說的鏈表為例, 顯然是應(yīng)該從鏈表的開頭開始查找. 那么,在鏈表開頭的是些什么東東呢? The criteria garbage collector uses to judge whether an object is no longer needed is that an object can be released when the object does have any reference. In some complicated cases, it happends that the first object refers to the second object, and the second object points to the third object, etc. It is looking like a chain of single linked nodes. Then the question is : where does the garbage collector begins to find objects no longer needed? For the example of the single linked node chain, we can say it is obvious garbage collector starts from the beginning of the chain. Then the next question is: what are the stuff at the beginning of the chain.

      是局部變量, 全局變量, 靜態(tài)變量, 指向托管堆的CPU寄存器. 在CLR中,它們被稱之為根. The answer is : local variables, global variables, static variables, the CPU registers pointing to managed heap. In CLR, they are called “the roots”.

      有了開始點(diǎn), 垃圾收集器接下來怎么做呢? Got the roots, what will garbage collector do next?

      創(chuàng)建一個(gè)圖, 一個(gè)描述對(duì)象間引用關(guān)系的圖. Build a graph, which shows the reference relationship among objects.
      垃圾收集器首先假定所有在托管堆里面的對(duì)象都是不可到達(dá)的(或者說沒有被引用的,不再需要的), 然后從根上的那些變量開始, 針對(duì)每一個(gè)根上的變量, 找出其引用的托管堆上的對(duì)象, 將找到的對(duì)象加入這個(gè)圖, 然后再沿著這個(gè)對(duì)象往下找,看看它有沒有引用另外一個(gè)對(duì)象, 有的話,繼續(xù)將找到的對(duì)象加入圖中,如果沒有的話, 就說明這條鏈已經(jīng)找到尾部了. 垃圾收集器就去從根上的另外一個(gè)變量開始找, 直到根上的所有變量都找過了, 然后垃圾收集器才停止查找. 值得一提的是, 在查找過程中, 垃圾收集器有些小的優(yōu)化, 如: 由于對(duì)象間的引用關(guān)系可能是比較復(fù)雜的, 所以有可能找到一個(gè)對(duì)象, 而此對(duì)象已經(jīng)加入圖了, 那么垃圾收集器就不再在此條鏈上繼續(xù)查找, 轉(zhuǎn)去其他的鏈上繼續(xù)找. 這樣對(duì)垃圾收集器的性能有所改善.

      First garbage collector supposes all the objects in managed heap are not reachable( do not have reference, or no longer needed). Then start from the variables in the roots. For each of the variable in the roots, search the object the variable refers to, and add the found object into the graph, and search again after the found object for next refered object, etc. Check whether the found object has next reference. If has, continue to add the next found object into the graph. If not, it means this is the end of the chain, then stop searching on the chain, continue on next variable in the roots, keep searching on roots, until all the searching are finished. In the searching process, garbage collector has some optimization to improve the performance. Like: Because the reference relationship could be complicated among objects, it is possible to find an object that has been added into the graph, then garbage collector stops searching on the chain, continue to search next chain. This way helps on performance of garbage collection.

      垃圾收集器建好這個(gè)圖之后, 剩下那些沒有在這個(gè)圖中的對(duì)象就是不再需要的. 垃圾收集器就可以回收它們占用的空間.After buidling the reference graph among objects, the objects not in the graph are no longer needed objects. Garbage collector could release the memory space occupied by the no longer needed objects.

      分享:如何改變.net網(wǎng)站的默認(rèn)解決方案位置
      1. 把該網(wǎng)站以前的解凍方案刪除(默認(rèn)位置:我的文檔\Visual Studio 2005\Projects\XX\xx.sln) 2. 打開VS2005,選擇

      來源:模板無憂//所屬分類:.Net教程/更新時(shí)間:2009-07-19
      相關(guān).Net教程