国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

.NET的內(nèi)存分配和釋放解析

2017-03-27 14:20:19王紅偉王紅紀(jì)
科技資訊 2017年2期

王紅偉+王紅紀(jì)

摘 要:在面向?qū)ο蟮某绦颦h(huán)境中,任何一個(gè)程序都需要使用到計(jì)算機(jī)資源,程序中的每一個(gè)類型都代表著程序需要的資源。程序在使用這些資源過(guò)程中,要經(jīng)歷一個(gè)分配內(nèi)存給類型資源、初始化內(nèi)存及數(shù)據(jù)類型、訪問(wèn)數(shù)據(jù)成員信息、銷毀并清理資源、釋放內(nèi)存的過(guò)程。

關(guān)鍵詞:.NET 內(nèi)存分配 垃圾回收器 內(nèi)存釋放

中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1672-3791(2017)01(b)-0028-02

在.NET中,內(nèi)存中的資源(即所有二進(jìn)制信息的集合)分為“托管資源”和“非托管資源”。托管資源必須接受.NET的CLR(通用語(yǔ)言運(yùn)行時(shí),.NET框架的底層)的管理(諸如內(nèi)存類型安全性檢查),而非托管資源則不必接受.NET的通用語(yǔ)言運(yùn)行時(shí)的管理。.NET對(duì)內(nèi)存的管理首先是管理托管資源和非托管資源所占用的內(nèi)存分配和釋放;其次是尋找不再使用的對(duì)象,釋放其占用的內(nèi)存,以及釋放非托管資源所占用的內(nèi)存;最后是釋放內(nèi)存之后,出現(xiàn)了內(nèi)存碎片,垃圾回收器移動(dòng)一些對(duì)象,以得到整塊的內(nèi)存,同時(shí)所有的對(duì)象引用都將被調(diào)整為指向?qū)ο笮碌拇鎯?chǔ)位置。

1 內(nèi)存分配

.NET平臺(tái)引入高效的、安全的托管執(zhí)行環(huán)境——通用語(yǔ)言運(yùn)行時(shí)。通用語(yǔ)言運(yùn)行時(shí)管理內(nèi)存的區(qū)域,主要有三塊,依次是:(1)線程的堆棧,用于分配值類型實(shí)例對(duì)象,它主要由操作系統(tǒng)管理,當(dāng)值類型實(shí)例所在方法結(jié)束時(shí),其存儲(chǔ)單位自動(dòng)釋放,堆棧的執(zhí)行效率高,但存儲(chǔ)容量有限。(2)GC堆(中文名稱垃圾回收,是.NET中對(duì)內(nèi)存管理的一種功能),用于分配小對(duì)象實(shí)例。(3)LOH(Large Object Heap)堆,用于分配大對(duì)象實(shí)例。

.NET CLR將所有資源分配到托管堆上,當(dāng)一個(gè)線程初始化,運(yùn)行時(shí)將預(yù)定一塊未使用連續(xù)的地址空間。這塊地址空間就是托管堆。堆中同時(shí)維護(hù)著一個(gè)指針,我們叫它下一個(gè)對(duì)象指針。這個(gè)指針告訴我們下一個(gè)程序?qū)ο髮⒈环峙涞蕉阎械氖裁次恢谩T诔绦虺跗?,這個(gè)指針被設(shè)置到最基本的內(nèi)存地址。使用new運(yùn)算符創(chuàng)建對(duì)象時(shí),運(yùn)行庫(kù)都從托管堆為該對(duì)象分配內(nèi)存。只要托管堆中有地址空間可用,并且空間中夠用,下一個(gè)對(duì)象指針將指向堆中的此對(duì)象,對(duì)象構(gòu)造函數(shù)被調(diào)用,最后返回對(duì)象內(nèi)存地址。

2 內(nèi)存釋放與回收

當(dāng)一個(gè)程序使用new操作符創(chuàng)建一個(gè)新對(duì)象時(shí),可能沒(méi)有足夠的地址空間來(lái)放置它。為了檢測(cè)地址空間是否足夠,托管堆會(huì)嘗試把對(duì)象放到下一個(gè)對(duì)象指針位置,如果下一個(gè)對(duì)象指針移動(dòng)到超過(guò)地址空間邊界,那說(shuō)明堆已滿,GC則進(jìn)行垃圾回收。垃圾回收器跟蹤并回收托管內(nèi)存中分配的對(duì)象,定期執(zhí)行垃圾回收以回收分配給沒(méi)有有效引用的對(duì)象的內(nèi)存。當(dāng)使用可用內(nèi)存不能滿足內(nèi)存請(qǐng)求時(shí),垃圾回收會(huì)自動(dòng)進(jìn)行。在進(jìn)行垃圾回收時(shí),垃圾回收器首先搜索內(nèi)存中的托管對(duì)象,然后從托管代碼中搜索被引用的對(duì)象并標(biāo)記為有效,接著釋放沒(méi)有被標(biāo)記為有效的對(duì)象并收回內(nèi)存,最后整理內(nèi)存將有效對(duì)象挪動(dòng)到一起。

3 內(nèi)存釋放與回收的模式

我們創(chuàng)建的類不包含非托管資源時(shí),只需要直接使用,CLR自然會(huì)判斷其生命周期結(jié)束而后回收相應(yīng)的托管資源。但如果我們創(chuàng)建了含有非托管資源的類,CLR提供其他機(jī)制來(lái)幫助自動(dòng)釋放非托管資源。在.NET中提供三種模式來(lái)回收內(nèi)存資源:dispose模式、finalize方法、close方法。

(1)dispose提供一種顯式釋放內(nèi)存資源的方法。此方法用于更快更具操作性進(jìn)行釋放,可以使用此方法。結(jié)構(gòu)和類型都可以實(shí)現(xiàn)IDispose,因?yàn)槭菍?duì)象本身釋放非托管資源,所以可以用對(duì)象名來(lái)顯式的調(diào)用來(lái)實(shí)現(xiàn)內(nèi)存釋放。所有實(shí)現(xiàn)IDisposable接口的類對(duì)象都必須調(diào)用這一方法。.NET基類庫(kù)中許多類型都實(shí)現(xiàn)IDisposable接口,有時(shí)給這一方法提供另外的別名,例如:輸入輸出類中的Close方法。

(2)finalize方法是.NET的內(nèi)部的一個(gè)釋放內(nèi)存資源的方法,由垃圾回收器自己調(diào)用。此方法被不斷重寫(xiě),原因是一些類通過(guò)平臺(tái)調(diào)用服務(wù)或復(fù)雜的COM互操作性任務(wù)使用了非托管資源。對(duì)象類中也有這一方法,但創(chuàng)建的類不能重寫(xiě)此方法,可以通過(guò)析構(gòu)函數(shù)來(lái)達(dá)到同樣的效果。這一方法的作用是保證.NET對(duì)象能在垃圾回收時(shí)清除非托管資源。通用語(yǔ)言運(yùn)行時(shí)在托管堆上分配對(duì)象時(shí),運(yùn)行庫(kù)自動(dòng)確定該對(duì)象是否提供一個(gè)自定義的Finalize方法。如果是這樣,對(duì)象會(huì)被標(biāo)記為可終結(jié)的,同時(shí)一個(gè)指向這個(gè)對(duì)象的指針被保存在名為終結(jié)隊(duì)列的內(nèi)部隊(duì)列中。終結(jié)隊(duì)列是一個(gè)由垃圾回收器維護(hù)的表,它指向每一個(gè)在從堆上刪除之前必須被終結(jié)的對(duì)象。Finalize最大作用是確保非托管資源一定被釋放。

(3)close和dispose其實(shí)一樣。一些類中沒(méi)有定義dispose的方法,只定義了close方法,而close實(shí)質(zhì)上也是調(diào)用了一個(gè)私有的dispose方法,而finalize其實(shí)也是調(diào)用一個(gè)不對(duì)外公開(kāi)的dispose方法。

4 內(nèi)存釋放與回收過(guò)程

垃圾回收時(shí)機(jī):托管堆滿,內(nèi)存分配即將不足。程序員可以手動(dòng)調(diào)用GC.Collect()。垃圾確認(rèn):通過(guò)根來(lái)尋找可達(dá)的對(duì)象,并做標(biāo)記,然后回收沒(méi)有標(biāo)記的對(duì)象。垃圾回收:內(nèi)存回收,實(shí)現(xiàn)了Finalize方法的對(duì)象用此方法實(shí)現(xiàn)內(nèi)存回收。內(nèi)存轉(zhuǎn)移、合并:垃圾回收后使得內(nèi)存不連續(xù)、零碎,.NET會(huì)將利用的內(nèi)存合并為連續(xù)的塊,然后更新對(duì)象的指針。

5 內(nèi)存釋放與回收時(shí)的注意事項(xiàng)

值類型(包括引用和對(duì)象實(shí)例)和引用類型的對(duì)象,當(dāng)它們出了作用域后會(huì)自動(dòng)釋放所占內(nèi)存。因?yàn)樗鼈兌急4嬖凇岸褩!敝校@是一種先進(jìn)后出數(shù)據(jù)結(jié)構(gòu)。引用類型的引用所指向的對(duì)象實(shí)例保存在“堆”中,而堆因?yàn)槭且粋€(gè)自由存儲(chǔ)空間,所以它并沒(méi)有像“堆?!蹦菢佑猩嫫冢ā岸褩!钡脑貜棾龊缶痛砩嫫诮Y(jié)束,也就代表釋放了內(nèi)存),“垃圾回收器”只對(duì)這塊區(qū)域起作用。 “垃圾回收器”并不會(huì)立即執(zhí)行(當(dāng)堆中的資源需要釋放時(shí)),因?yàn)椤袄厥掌鳌钡恼{(diào)用是比較消耗系統(tǒng)資源的,因此,不能經(jīng)常被調(diào)用。這時(shí),用戶可以調(diào)用方法System.GC.Collect()來(lái)強(qiáng)制執(zhí)行“垃圾回收器”??蓪?shí)現(xiàn)Dispose()方法來(lái)顯式釋放由對(duì)象使用的所有未托管資源。垃圾收集器在釋放了它能釋放的所有對(duì)象后,就會(huì)壓縮其他對(duì)象,把他們都移動(dòng)回堆的端部,再次形成一個(gè)連續(xù)的塊。

參考文獻(xiàn)

[1] Neo_Wu[EB/OL].http://blog.csdn.net/neo_ustc/article/details/12883185,2013.

[2] .Net垃圾回收中涉及的名稱[EB/OL].http://www.cnblogs.com/hfclytze/p/3706326.html,2014.

[3] binbingg[EB/OL].http://www.cnblogs.com/chinafine/articles/864776.html,2016.

[4] 賀俊峰..Net垃圾回收器管理應(yīng)用程序的內(nèi)存分配和釋放[EB/OL].http://hejunfeng.blog.51cto.com/3182120/627153.

[5] http://jingyan.baidu.com/article/642c9d34d7ec8f644a46f7fb.html,2013.

[6] Depaul[EB/OL].http://blog.csdn.net/leewhoee/article/details/17291953,2014.

永善县| 孟津县| 出国| 崇州市| 江油市| 扶绥县| 南昌市| 昆山市| 类乌齐县| 阳西县| 霍城县| 三原县| 贞丰县| 台北市| 类乌齐县| 井陉县| 香河县| 闻喜县| 长丰县| 宣汉县| 通海县| 邛崃市| 平远县| 阳谷县| 依安县| 廊坊市| 共和县| 麟游县| 青岛市| 桑植县| 无为县| 横山县| 万山特区| 云霄县| 阿图什市| 简阳市| 荃湾区| 湛江市| 灵璧县| 富锦市| 中阳县|