2011-10-15 17:58:56

 

2011-10-15 17:58:56


 Android系統的運行時庫層代碼是用C++來編寫的,用C++來寫代碼最容易出錯的地方就是指針了,
 
 一旦使用不當,輕則造成內存泄漏,重則造成系統崩潰。不過系統爲我們提供了智能指針,避免出現上述問題,
 
 本文將系統地分析Android系統智能指針(輕量級指針、強指針和弱指針)的實現原理。

    在使用C++來編寫代碼的過程中,指針使用不當造成內存泄漏一般就是因爲new了一個對象並且使用完之後,忘記了delete這個對象,
   
    而造成系統崩潰一般就是因爲一個地方delete了這個對象之後,其它地方還在繼續使原來指向這個對象的指針。爲了避免出現上述問題,
   
    一般的做法就是使用引用計數的方法,每當有一個指針指向了一個new出來的對象時,就對這個對象的引用計數增加1,每當有一個指針不再使用這個對象時,
   
    就對這個對象的引用計數減少1,每次減1之後,如果發現引用計數值爲0時,那麼,就要delete這個對象了,
   
    這樣就避免了忘記delete對象或者這個對象被delete之後其它地方還在使用的問題了。但是,如何實現這個對象的引用計數呢?肯定不是由開發人員來手動地維護了,
   
    要開發人員時刻記住什麼時候該對這個對象的引用計數加1,什麼時候該對這個對象的引用計數減1,一來是不方便開發,二來是不可靠,一不小心哪裏多加了一個1或者多減了一個1,
   
    就會造成災難性的後果。這時候,智能指針就粉墨登場了。首先,智能指針是一個對象,不過這個對象代表的是另外一個真實使用的對象,當智能指針指向實際對象的時候,
   
    就是智能指針對象創建的時候,當智能指針不再指向實際對象的時候,就是智能指針對象銷燬的時候,我們知道,在C++中,對象的創建和銷燬時會分別自動地調用對象的構造函數和
   
    析構函數,這樣,負責對真實對象的引用計數加1和減1的工作就落實到智能指針對象的構造函數和析構函數的身上了,這也是爲什麼稱這個指針對象爲智能指針的原因。
    
    在計算機科學領域中,提供垃圾收集(Garbage Collection)功能的系統框架,即提供對象託管功能的系統框架,例如Java應用程序框架,也是採用上述的引用計數技術方案來實現的,
   
    然而,簡單的引用計數技術不能處理系統中對象間循環引用的情況。考慮這樣的一個場景,系統中有兩個對象A和B,在對象A的內部引用了對象B,而在對象B的內部也引用了對象A。
   
    當兩個對象A和B都不再使用時,垃圾收集系統會發現無法回收這兩個對象的所佔據的內存的,因爲系統一次只能收集一個對象,而無論系統決定要收回對象A還是要收回對象B時,
   
    都會發現這個對象被其它的對象所引用,因而就都回收不了,這樣就造成了內存泄漏。這樣,就要採取另外的一種引用計數技術了,即對象的引用計數同時存在強引用和弱引用兩種計數,
   
    例如,Apple公司提出的Cocoa框架,當父對象要引用子對象時,就對子對象使用強引用計數技術,而當子對象要引用父對象時,就對父對象使用弱引用計數技術,
   
    而當垃圾收集系統執行對象回收工作時,只要發現對象的強引用計數爲0,而不管它的弱引用計數是否爲0,都可以回收這個對象,但是,如果我們只對一個對象持有弱引用計數,
   
    當我們要使用這個對象時,就不直接使用了,必須要把這個弱引用升級成爲強引用時,才能使用這個對象,在轉換的過程中,如果對象已經不存在,那麼轉換就失敗了,
   
    這時候就說明這個對象已經被銷燬了,不能再使用了。
 
    瞭解了這些背景知識後,我們就可以進一步學習Android系統的智能指針的實現原理了。Android系統提供了強大的智能指針技術供我們使用,
   
    這些智能指針實現方案既包括簡單的引用計數技術,也包括了複雜的引用計數技術,即對象既有強引用計數,也有弱引用計數,對應地,
   
    這三種智能指針分別就稱爲輕量級指針(Light Pointer)、強指針(Strong Pointer)和弱指針(Weak Pointer)。無論是輕量級指針,還是強指針和弱指針,
   
    它們的實現框架都是一致的,即由對象本身來提供引用計數器,但是它不會去維護這個引用計數器的值,而是由智能指針來維護,就好比是對象提供素材,
   
    但是具體怎麼去使用這些素材,就交給智能指針來處理了。由於不管是什麼類型的對象,它都需要提供引用計數器這個素材,在C++中,
   
    我們就可以把這個引用計數器素材定義爲一個公共類,這個類只有一個成員變量,那就是引用計數成員變量,其它提供智能指針引用的對象,都必須從這個公共類繼承下來,
   
    這樣,這些不同的對象就天然地提供了引用計數器給智能指針使用了。總的來說就是我們在實現智能指會的過程中,第一是要定義一個負責提供引用計數器的公共類,
   
    第二是我們要實現相應的智能指針對象類,後面我們會看到這種方案是怎麼樣實現的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章