1. 程式人生 > >深入理解dvm和jvm

深入理解dvm和jvm

學習android想要對android的framwork或者執行機制有深入瞭解,dvm是一定要知道的。即使是在面試時被問起dvm和jvm也是很平常的,網上關於dvm和jvm的文章很多,但是沒有一篇能把dvm的前世今生徹頭徹尾的講清的,在這裡我結合網路資源和自身對編譯原理以及嵌入式的理解在這裡斗膽揭示下dvm的全貌,不對的地方歡迎再下方留言。

kernel啟動流程

眾所周知,android使用的是linux核心的,那麼android和linux的關係就很微妙了;android是在linux核心的基礎針對硬體和特殊的執行需求做了深度優化的,例如,對於電源管理模組、程序排程模組、記憶體管理模組等等,優化後的kernel可以更高效更符合使用者對手機的使用習慣,以及對手機硬體的高效支援。下面正式講講android是如何從一個破板子,就執行起kernel了,然後又運行了android、運行了什麼dvm的。。。

  1. cpu上電,執行0xFFF0地址的4k程式,4k程式將bootloader程式搬運到ram中執行,bootloader負責初始化硬體資源和載入kernel,然後將控制權交給kernel。
  2. kernel得到控制權後,開始自啟。第一個執行的函式是start_kernel
  3. start_kernel中呼叫下列一系列函式
    page_address_init();//頁表地址初始化
    sched_init();
    page_alloc_init();//記憶體分配初始化,請看mmu和記憶體管理
    init_IRQ();//中斷向量初始化
    softirq_init();//軟中斷初始化
    console_init();//終端初始化
    calibrate_delay();
    vfs_caches_init();//虛擬檔案系統(vfs)初始化
    rest_init();//這就是最後建立init0程序的函式,init0程序會建立android的受精卵程序Zygote。
    這裡寫圖片描述

    Zygote程序啟動標誌著進入裡android時代

kernel程序和dvm程序

kernel程序和dvm程序有什麼區別?
答案是一樣的。

rest_init函式都做了什麼

首先完成了硬體驅動的初始化,沒有硬體驅動,上層軟體就是個殼子
然後啟動kernel第一個程序,init程序是負責fork所有其他子程序,init程序優先順序最高,為1,init程序會fork出Zygote程序;Zygote程序是android的最高級別程序,所有android的程序都是由Zygote程序fork出來的,並且android子程序都是呼叫dvm虛擬機器執行我們的app。所以每個app都是kernel中的一個單獨程序,程序之間複製複製父程序上下文,但是又不會相互干擾。
如下圖所示,Fork()橙色箭頭左邊是Zygote程序,右邊是創建出的Zygote‘子程序;然後Zygote’ 子程序將執行流程交給應用程式A,Android程式開始執行。
新生成的應用程式A會使用已有Zygote父程序的庫與資源的連線資訊,所以執行速度很快。
這裡寫圖片描述

dvm和jvm區別

Dalvik虛擬機器是Google等廠商合作開發的Android移動裝置平臺的核心組成部分之一。它可以支援已轉換為.dex(即Dalvik Executable)格式的Java應用程式的執行,.dex格式是專為Dalvik設計的一種壓縮格式,適合記憶體和處理器速度有限的系統。(dx 是一套工具,可以將 Java .class 轉換成 .dex 格式. 一個dex檔通常會有多個.class。由於dex有時必須進行最佳化,會使檔案大小增加1-4倍,以ODEX結尾。)  

1、執行的位元組碼不一樣

jvm: java->class->jar
dvm:java->class->dex

這裡寫圖片描述 

2、 基於的架構不一樣

Java JIT(just in time)即時編譯器是sun公司採用了hotspot虛擬機器取代其開發的classic vm之後引入的一項技術,目的在於提高java程式的效能,改變人們“java比C/C++慢很多”這一尷尬印象。說起來是編譯器,但此編譯器與通常說的javac那個編譯器不同,它其實是將位元組碼編譯為硬體可執行的機器碼的。

Dalvik 基於暫存器,而 JVM 基於棧。基於暫存器的虛擬機器對於更大的程式來說,在它們編譯的時候,花費的時間更短。 JVM位元組碼中,區域性變數會被放入區域性變量表中,繼而被壓入堆疊供操作碼進行運算,當然JVM也可以只使用堆疊而不顯式地將區域性變數存入變量表中。Dalvik位元組碼中,區域性變數會被賦給65536個可用的暫存器中的任何一個,Dalvik指令直接操作這些暫存器,而不是訪問堆疊中的元素。

3、Dalvik 和 Java SDK的SDK不同。

4、Dalvik 和 Java 執行環境的區別    

5、Dalvik 經過優化,允許在有限的記憶體中同時執行多個虛擬機器的例項,並且每一個Dalvik 應用作為一個獨立的Linux 程序執行。獨立的程序可以防止在虛擬機器崩潰的時候所有程式都被關閉。

6、Dalvik虛擬機器在android2.2之後使用JIT (Just-In-Time)技術,與傳統JVM的JIT並不完全相同, 

7、Dalvik虛擬機器有自己的 bytecode,並非使用 Java bytecode。