免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
垃圾回收GC:.Net自動內(nèi)存管理 上(一)內(nèi)存分配

垃圾回收GC:.Net自動內(nèi)存管理 上(一)內(nèi)存分配

前言


.Net下的GC完全解決了開發(fā)者跟蹤內(nèi)存使用以及控制釋放內(nèi)存的窘態(tài)。然而,你或許想要理解GC是怎么工作的。此系列文章中將會解釋內(nèi)存資源是怎么被合理分配及管理的,并包含非常詳細(xì)的內(nèi)在算法描述。同時(shí),還將討論GC的內(nèi)存清理流程及什么時(shí)清理,怎么樣強(qiáng)制清理。


引子


為你的應(yīng)用程序?qū)崿F(xiàn)合理的資源管理是一件困難的,乏味的工作。這可能會把你的注意力從你當(dāng)前正在解決的實(shí)際問題中轉(zhuǎn)移到它身上。那么,如果有一個現(xiàn)有的機(jī)制為開發(fā)者管理令人厭惡的內(nèi)存管理,會不會是件快意人心的事?答案是YES!在.Net中, 有一種垃圾回收機(jī)制叫GC。


每一個程序都需要使用一些計(jì)算機(jī)資源,如內(nèi)存,顯卡,網(wǎng)絡(luò),數(shù)據(jù)庫等等。實(shí)際上,在一個面向?qū)ο蟮沫h(huán)境里,每一個類型都代表著程序需要使用的資源。如果要用到這些資源,則需要分配內(nèi)存呈現(xiàn)這個類型。下面是訪問這些資源的步驟:

  1. 分配內(nèi)存給類型資源。
  2. 初始化內(nèi)存和類型資源并使資源可用。
  3. 利用這些資源來訪問類型實(shí)例成員信息(按需重復(fù))。
  4. 銷毀并清理資源
  5. 釋放內(nèi)存

這看起來很簡單,但卻是程序錯誤的根本來源。有多少次程序員忘記釋放閑置內(nèi)存?有多少次程序員試圖訪問已經(jīng)釋放的內(nèi)存?

      

這兩種BUG是最糟糕的情況,因?yàn)樗鼈儗?dǎo)制的異常結(jié)果和發(fā)生時(shí)間是不可預(yù)測的。對于其它的BUG,當(dāng)你看到程序運(yùn)行錯誤時(shí),直接修復(fù)就行了。這兩種BUG最容易造成程序資源泄漏(浪費(fèi)內(nèi)存)和程序?qū)ο蟊罎?不穩(wěn)定),而且還會促使應(yīng)用程序在不可預(yù)知的時(shí)間產(chǎn)生不可預(yù)知的行為。當(dāng)然了,有許多工具可用于跟蹤監(jiān)測這種BUG。

     

當(dāng)我們測試GC時(shí),你應(yīng)該知道它徹底解決了開發(fā)者跟蹤內(nèi)存使用及確定何時(shí)釋放內(nèi)存的問題。然而,垃圾回收GC并不了解任何關(guān)于類型在內(nèi)存中代表的資源。這意味著,GC不知道也不會去執(zhí)行第四步:銷毀并清理資源。在.net framework中,程序員在方法Close,Dispose,F(xiàn)inalize中編寫有關(guān)銷毀清理資源的代碼,后續(xù)文章中會介紹。不過,GC能夠決定什么時(shí)去自動調(diào)用這些方法。

    

有一些類型資源不需要清理。如,Rectangle類型可以通過銷毀它在內(nèi)存中的left,right,width和height從而被徹底清理。另一方面,一個文件類型資源或網(wǎng)絡(luò)連接類型資源則需要非常明確的清理代碼來銷毀。我將解釋怎么適當(dāng)?shù)赝瓿蛇@些任務(wù)。現(xiàn)在,讓我們了解一下內(nèi)存是怎么分配的以及資源是怎么初始化的。


內(nèi)存分配



.NET CLR將所有資源分配到托管堆上,這有點(diǎn)像C語言中的堆但是你不用去釋放資源因?yàn)殚e置資源在.NET中將被自動釋放?,F(xiàn)在就有一個問題了,托管堆是怎么知道一個對象什么時(shí)候?qū)⒉辉俦怀绦蚴褂??我將簡單介紹一下。
    
現(xiàn)今有很多的GC算法。每一個算法都針對某一特定環(huán)境進(jìn)行調(diào)優(yōu),進(jìn)而獲得最好的性能。這篇文章著重于.NET CLR使用的GC算法。讓我們從基本概念開始。
      
當(dāng)一個線程初始化了,運(yùn)行時(shí)將預(yù)定一塊未使用的連續(xù)的地址空間。這塊地址空間就是托管堆深入淺出圖解C#堆與棧 C# Heap(ing) VS Stack(ing)。堆中同時(shí)維護(hù)著一個指針,我們叫它下一個對象指針。這個指針告訴我們下一個程序?qū)ο髮⒈环峙涞蕉阎械氖裁次恢?。在程序初期,這個指針被設(shè)置到最基本(可以理解為第一位置)的內(nèi)存地址。

程序使用new關(guān)鍵字創(chuàng)建一個新對象。這個操作首先需要確定預(yù)定的地址空間是否足夠存儲新對象(內(nèi)存空間是否足夠)。如果足夠,NextObjPtr(下一個對象指針)將指向堆中的此對象,對象構(gòu)造函數(shù)被調(diào)用,最后返回對象內(nèi)存地址。

托管堆(對堆與棧疑惑的朋友可以參考:深入淺出圖解C#堆與棧):

(NextObjPtr:下一個對象指針)


此時(shí),NextObjPtr將跳過此對象并指向下一個將要被存入的對象的內(nèi)存地址。如上圖,托管堆中有三個對象:A,B,C。下一個對象將會被放置到NextObjPtr指向的地址(即緊跟C之后)。

現(xiàn)在讓我們看看C語言的堆怎么分配內(nèi)存的。在c語言堆中,為一個對象分配內(nèi)存需要通過一個數(shù)據(jù)結(jié)構(gòu)鏈表。一旦發(fā)現(xiàn)一個較大的塊,則進(jìn)行分割塊,然后鏈表節(jié)點(diǎn)中的指針需要調(diào)整修改以保證所有數(shù)據(jù)原封不動(C語言不熟,原文:In a C-runtime heap, allocating memory for an object requires walking though a linked list of data structures. Once a large enough block is found, that block has to be split, and pointers in the linked list nodes must be modified to keep everything intact. )。對.NET中的托管堆來講,對象分配簡單,只需要向指針添加一個值,相比而言這是非??斓?。事實(shí)證明,在托管堆中分配一個對象幾乎像在線程棧里分配內(nèi)存一樣快!
   

到現(xiàn)在為止,聽起來托管堆在速度上和實(shí)現(xiàn)簡易性上要遠(yuǎn)遠(yuǎn)地優(yōu)秀于C語言的堆。但是,要使托管堆擁有這些優(yōu)點(diǎn)需要一個大前提:地址空間和存儲空間是無限大的。當(dāng)然,這有些不切實(shí)際,但托管堆必須使用一些機(jī)制原理來使這個所謂的假設(shè)成立。這個機(jī)制就是垃圾回收GC。讓我們看看它是怎么工作的。
      

當(dāng)一個程序使用new操作符創(chuàng)建一個新對象時(shí),可能沒有足夠的地址空間來放置它。為了檢測地址空間是否足夠,托管堆會償試把對象放到NextObjPtr位置,如果NextObjPtr移動到超過地址空間邊界,那說明堆已滿,GC則進(jìn)行垃圾回收。

   

實(shí)際上,GC會在第0代(后續(xù)文章會介紹GC中的代)被占滿時(shí)進(jìn)行垃圾回收。簡單來說,GC中的代是GC實(shí)現(xiàn)的一種機(jī)制用來提高程序性能。原理上就是最新創(chuàng)建的對象屬于GC的年輕一代,應(yīng)用程序生命周期中較早創(chuàng)建的對象屬于較老一代。把對象分成不同的代可以讓GC知道要進(jìn)行垃圾回收的特定代,而不是回收整個托管堆。


總結(jié)

本篇文章是為了讓大家對垃圾回收GC和內(nèi)存分配有一個初步的認(rèn)識,不得不說了解內(nèi)存分配對于一個程序員是很重要的,如果你想寫高性能代碼的話。雖然我們不必像使用C語言那樣手工分配內(nèi)存,但對內(nèi)存分配茫然無知的程序員多多少少會被鄙視一點(diǎn)點(diǎn)的(只是一點(diǎn)點(diǎn),好吧,沒有任何攻擊性,請不要誤解)。下一篇文章將繼續(xù)介紹垃圾回收GC的自動內(nèi)存管理:內(nèi)存算法。


翻譯:http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
.Net 垃圾回收機(jī)制原理(一)
.NET下的內(nèi)存分配機(jī)制
[你必須知道的.NET]第十九回:對象創(chuàng)建始末(下) - Anytao - 博客園
C#釋放資源
堆棧和托管堆 c#
Go 不需要 Java 風(fēng)格的 GC
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服