1. 程式人生 > >Android虛擬機器的理解和記憶體管理

Android虛擬機器的理解和記憶體管理

虛擬機器很小,空間很小,談談移動裝置的虛擬機器的大小限制 16M ,
談談載入圖片的時候怎麼處理大圖片的,
outmemoryException
BitmapFactory.option 
垃圾回收,沒有引用的物件,在某個時刻會被系統gc掉 .

Dalvik和標準Java虛擬機器(JVM)首要差別
Dalvik 基於暫存器,而 JVM 基於棧。
基於暫存器虛擬機器對於編譯後變大的程式來說,在它們執行的時候,花費的時間更短。
Dalvik和Java執行環境的區別
1:Dalvik主要功能:完成物件生命週期管理,堆疊管理,執行緒管理,安全和異常管理,以及垃圾回收等等重要功能。
2:Dalvik負責:程序隔離和執行緒管理,每一個Android應用在底層都會對應一個獨立的Dalvik
虛擬機器例項,其程式碼在虛擬機器的解釋下得以執行。
3:不同於Java虛擬機器執行java位元組碼,Dalvik虛擬機器執行的是其專有的檔案格式Dex
4:dex檔案格式可以減少整體檔案尺寸,提高I/O操作的類查詢速度。
5:odex是為了在執行過程中進一步提高效能,對dex檔案的進一步優化。
6:所有的Android應用的執行緒都對應一個Linux執行緒,虛擬機器因而可以更多的依賴作業系統執行緒排程和管理機制。

7:有一個特殊的虛擬機器程序Zygote,他是虛擬機器例項的孵化器。

      它在系統啟動的時候就會產生,它會完成虛擬機器的初始化,庫的載入,預製類庫和初始化的操作。

      如果系統需要一個新的

虛擬機器例項,它會迅速複製fork()自身,以最快的資料提供給系統。對於一些只讀的系統庫,所有虛擬機器例項都和Zygote共享一塊記憶體區域。

8:Dalvik是由Dan Bornstein編寫的,名字來源於他的祖先曾經居住過名叫Dalvík的小漁村,村子位於冰島

        許多GC實現都是在物件開頭的地方留一小塊空間給GC標記用。Dalvik VM則不同,在進行GC的時候會單獨申請一塊空間,以點陣圖的形式來儲存整個堆上的物件的標記,在GC結束後就釋放該空間。 

    Dalvik是執行的時候編譯+執行,安裝比較快,開啟應用比較慢,應用佔用空間小;

    ART是安裝的時候就編譯好了,執行的時候直接就可以執行的,安裝慢,開啟應用快,佔用空間大。

用個比喻來說就是,騎自行車dalvik 是已經摺疊起來的自行車,每次騎都要先組裝自行車才能騎。

ART是已經組裝好的自行車,每次騎直接上車就能走人效率高在開啟的時候,執行中的速度是差不多的。

 Android的記憶體管理

   Android的程式由Java語言編寫,所以Android的記憶體管理與Java的記憶體管理相似。程式設計師通過new為物件分配記憶體,所有物件在java堆內分配空間;然而物件的釋放是由垃圾回收器來完成的。C/C++中的記憶體機制是“誰汙染,誰治理”,java的就比較人性化了,給我們請了一個專門的清潔工(GC)。

GC是垃圾收集的意思(GabageCollection),記憶體處理是程式設計人員容易出現問題的地方,忘記或者錯誤的記憶體回收會導致程式或系統的不穩定甚至崩潰,Java提供的GC功能可以自動監測物件是否超過作用域從而達到自動回收記憶體的目的,Java語言沒有提供釋放已分配記憶體的顯示操作方法。

垃圾回收的優點和原理 

   Java語言中一個顯著的特點就是引入了垃圾回收機制,使得Java程式設計師在編寫程式的時候不再需要考慮記憶體管理。垃圾回收可以有效的防止記憶體洩露,有效的使用可以使用的記憶體。垃圾回收器通常是作為一個單獨的低級別的執行緒執行,不可預知的情況下對記憶體堆中已經死亡的或者長時間沒有使用的物件進行清楚和回收,程式設計師不能實時的呼叫垃圾回收器對某個物件或所有物件進行垃圾回收。回收機制有分代複製垃圾回收和標記垃圾回收,增量垃圾回收。

    對於GC來說,當程式設計師建立物件時,GC就開始監控這個物件的地址、大小以及使用情況。通常,GC採用有向圖的方式記錄和管理堆(heap)中的所有物件。通過這種方式確定哪些物件是"可達的",哪些物件是"不可達的"。當GC確定一些物件為"不可達"時,GC就有責任回收這些記憶體空間。程式設計師可以手動執行System.gc(),通知GC執行,但是Java語言規範並不保證GC一定會執行

Android系統中GC出現記憶體洩露 

    導致記憶體洩漏主要的原因是,先前申請了記憶體空間而忘記了釋放。如果程式中存在對無用物件的引用,那麼這些物件就會駐留記憶體,消耗記憶體,因為無法讓垃圾回收器GC驗證這些物件是否不再需要。如果存在物件的引用,這個物件就被定義為"有效的活動",同時不會被釋放。要確定物件所佔記憶體將被回收,我們就要務必確認該物件不再會被使用。典型的做法就是把物件資料成員設為null或者從集合中移除該物件。但當局部變數不需要時,不需明顯的設為null,因為一個方法執行完畢時,這些引用會自動被清理。Java 記憶體洩露的根本原因就是 儲存了不可能再被訪問的變數型別的引用。

 Android的記憶體溢位

   因為系統為每一個dalvik虛擬機器分配的記憶體是有限的,它的最大堆大小一般是16M,有的機器為24M。也就是說我們所能利用的記憶體空間是有限的。如果我們的記憶體佔用超過了一定的水平就會出現OutOfMemory的錯誤。

 記憶體不夠用的原因

    由於我們程式的失誤,長期保持某些資源(如Context)的引用,造成記憶體洩露,資源造成得不到釋放。儲存了多個耗用記憶體過大的物件(如Bitmap),造成記憶體超出限制。 

     Framework 工作原理

Framework是android 系統對 linux kernel,lib庫等封裝,提供WMS,AMS,bind機制,handler-message機制等方式,供app使用。

Activity 是如何生成一個 view

1)Activity在attch方法的時候,會建立一個phonewindow(window的子類)

2)onCreate中的setContentView方法,會建立DecorView

3)DecorView 的addview方法,會把layout中的佈局載入進來。