《C#妹妹和Objective-C阿姨對話錄》(04)記憶體回收基礎--拆遷隊那點事

來源:互聯網
上載者:User

C#妹妹:作業系統天天說控制記憶體空間價格,咋還這麼高?我巨資購買的記憶體空間,後來發現竟然在硬碟上!虛擬記憶體!TMD!

Objective-C阿姨:作業系統全靠賣記憶體空間掙錢呢,你說價格能會降嗎?你看看那些程式員心理就平衡了,上海買房子結果買到江蘇,北京買房子結果買到河北,上班還要跨省,天天物件導向,到頭來連個對象都找不到。。

C#妹妹:靠,還是那句話“同一個世界 同一個噩夢”,你說記憶體空間賣光了咋辦?

Objective-C阿姨:把你記憶體空間回收了再賣給別人唄。


C#妹妹:
啊??!!人家在用的記憶體也回收啊?


Objective-C阿姨:
廢話,所有的記憶體都是作業系統的,只是借給你而已,作業系統讓你強制退出,你有辦法哇,把你幹掉然後發個新聞稿,說“死者目前情緒穩定”就好了。,不信看看你的《記憶體空間證》上使用到期日是多少?


C#妹妹:
60ms?!


真TMD的!這麼霸道,剛出台的《記憶體權法》就不管嗎?。


Objective-C阿姨:
作業系統執行的是1949年制定的《記憶體回收暫行條例》,已經暫行60多年了⋯⋯再說維穩是一切工作的核心!聽作業系統的話,讓你賣空間就買,讓你租就租,讓你釋放空間就釋放。特別是不用的對象趕快釋放掉。作業系統最討厭占茅坑不拉屎,輕則強制釋放,重則刪除程式,屍骨無存。。



C#妹妹:
還好,我們.NET程式請了個拆遷隊“記憶體回收行程”,專門幹這個事情。發現有用不到的對象,就主動還給作業系統了,早點把記憶體交給作業系統,興許給我的補償記憶體地段好點,別在給我安排什麼虛擬記憶體了,再說作業系統請的強制拆遷隊比較野蠻,盡量不麻煩他們了。


Objective-C阿姨:
呵呵,這是個好主意,不過.NET的記憶體回收行程咋知道你用不到這些對象?會不會把正用的對象也拆遷了?


C#妹妹:
所謂用不到,就是指代碼裡沒有再引用這些對象,.NET的所有對象都是由局部變數, 全域變數, 靜態變數, 指向託管堆的CPU寄存器,直接或者間接引用的,所以他們稱之為“根”,記憶體回收行程只需要從根出發,掃描這些根都引用了那些對象,並且全部記錄下來,餘下那些沒有記錄在冊的對象就都可以回收了。拆除都是記憶體回收行程自動進行的,程式員一般不用幹預了,複雜些的對象程式員要在方法Finalize()裡留下拆除方法,記憶體回收行程拆除非託管資源還不太在行,還是需要程式員指點一下的。這個過程非常安全,正在使用的對象是不會被回收的。


Objective-C阿姨:
記憶體回收行程咋知道對象間的參考關聯性的?


C#妹妹:
通過中繼資料啊,中繼資料描述了對象間的參考關聯性,並且.NET是型別安全的,對象指標只能指向相應的對象。


C#妹妹:
Objective-C阿姨,您的記憶體是如何管理的?


Objective-C阿姨:
Objective-C 2.0也是有記憶體回收機制的,但是只能在Mac OS X Leopard 以上的版本使用。


C#妹妹:
Leopard?豹子?是個什麼概念?


Objective-C阿姨:
這個要從Mac的版本說起,Mac OS X各個版本都是些貓科動物啦,現在最新版本是Snow Leopard,今年夏天Lion可能會發布。

下面的圖大概描述了Mac OS X的曆史。


哪像你們東家MS那麼沒有創意,今年一個窗戶,明年一個窗戶的造;天天造窗戶,哪有不碎玻璃的,這不三月底MS亞太地區研究中心大樓有玻璃掉下來了。


C#妹妹:
 ,還是繼續說記憶體回收的事情好哇。。。


Objective-C阿姨:
好吧,不批你們東家了。接著說,iPhone和iPad開發也是不支援記憶體回收的。


C#妹妹:
記憶體就需要程式員主動釋放是嗎?


Objective-C阿姨:
沒錯,不過Cocoa已經進行了簡化,看下面的例子吧。

首先要建立個被測試銷毀的對象

#import "House.h"//先建一個需要被刪除的對象 House類@implementation House-(void) dealloc//Objective-C在銷毀對象的時候會自動調用這個方法{    NSLog(@"房子被拆除了");    [super dealloc];}@end

這個House類是空的,裡邊只有個dealloc方法,能在拆除的時候顯示一條資訊“房子被拆除了”。


C#妹妹:好杯具的房子


Objective-C阿姨:下面的程式調用這個House對象

    House *h1=[House new];    NSLog(@"A.對象引用數量:%lu",[h1 retainCount]);    [h1 retain];    NSLog(@"B.對象引用數量:%lu",[h1 retainCount]);    [h1 release];    NSLog(@"C.對象引用數量:%lu",[h1 retainCount]);    [h1 release ];

先說[h1 retainCount]表示由多少個地方引用這個h1執行個體(House的執行個體),但是這個統計是否準確跟系統關係不大,主要看程式員統計的是否準確。

Objective-C使用的是引用計數的方式來檢測對象是否需要回收的,通過new、alloc建立的對象,計數器都是1。位置A對象剛被new執行個體話,所以引用數量是1;

如果這個對象被其他對象引用一次 調用一次 retain,引用的數量加1。位置B剛調用了retain,所以引用數量加1,所以顯示2。

如果引用的某個對象釋放該對象,調用一次release,引用的數量減1。位置C剛調用了release,所以引用數量減1,所以顯示1。

最後又調用了一次release,這個時候這個執行個體的引用數量為0,說明這個執行個體已經不再使用了,Objective-C會自動調用該對象的dealloc方法,回收資源。所以顯示了“房子被拆除了”~

與.NET的區別在於,.NET是記憶體回收行程自動統計那些對象已經沒有引用了,但是這個工作在Objective-C上,必須由程式員來完成。


上面的例子純粹為了展示retain、release、retainCount,程式員強制通過
retain、release改變引用數量的統計值(引用數量當然沒有改變),實際操作是肯定不會這樣進行的。

看下面這個稍微實戰一點的例子

    House *h1=[House new];//new後有一個引用    House *h2;    House *h3;    NSLog(@"%lu",[h1 retainCount]);//返回1        h2=h1;//h2也引用到這個對象上    [h1 retain];//所以手動更新引用計數器 為2    NSLog(@"%lu,%lu",[h1 retainCount],[h2 retainCount]);//返回2,2        h3=h2;//h3也跑過來湊熱鬧,這個時候對象有3個引用了    [h1 retain];//所以手動更新引用計數器 為3    NSLog(@"%lu,%lu,%lu",[h1 retainCount],[h2 retainCount],[h3 retainCount]);//返回3,3,3        h1=nil;//h1不再引用對象    [h3 release];//計數器減1    NSLog(@"%lu,%lu,%lu",[h1 retainCount],[h2 retainCount],[h3 retainCount]);//返回0,2,2        h2=nil;//h2也不再引用對象    [h3 release];//計數器減1    NSLog(@"%lu,%lu,%lu",[h1 retainCount],[h2 retainCount],[h3 retainCount]);//0,0,1        [h3 release];//計數減為0,表示該對象已經沒有引用了,拆遷隊一湧而上,回收對象的記憶體,並返回“房子被拆除了”

C#妹妹:基本看明白了,h1\h2\h3 三個變數折騰了半天,其實都是指向一個執行個體,不斷的通過retain和release同步對象的引用數量,一旦引用數量為0(不是真正的引用數量,是程式員統計出來的引用數量為0),拆遷隊就上去拆房子,對嗎?所以程式員統計對象引用的工作非常重要。而在.NET中,判斷引用為0的工作是由記憶體回收行程完成的。


Objective-C阿姨:
是的,Objective-C就是這樣管理記憶體的,不過這隻是剛剛開始,下次有更複雜的例子和更簡潔的方法。。

--

各位同學,本人學習Objective-C時間很短,學習Objective-C其實不是為了Mac、iPhone開發,並沒有實用,
其實是一個C#使用者學習Objective-C的學習筆記,學習的確切目的是協助我理解C#,畢竟沒有比較是不可能知道所謂C#的特點的
請大家批判的眼光看這個東西,如果發現和其他文章、書籍、評論、資料有衝突,請盡量以其他文章為準。並給我留言
也邀請所有高手積極拍磚,我正好用來蓋房子~~~
《C#妹妹和Objective-C阿姨對話錄》

(01)認識Objective-C--初次見面的問候 
(02)這就是類--阿姨的狗狗 
(03)NSString--再遇狗狗
(04)記憶體回收基礎--拆遷隊那點事
(05)自動釋放池--拆遷隊的外援 

        待續⋯⋯

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.