Android性能篇之(一)序言及JVM

android性能優化問題一直是android開發者遇到的難點之一。性能優化包含的內容廣而且比較深,內存的分配、管理、回收、溢出、優化,android進程機制,各種性能優化工具的使用,電量,界面流暢度等等,無一不是需要深入探究和分析才能辦得到的。

序言

       轉載請聲明,轉自【https://www.cnblogs.com/andy-songwei/p/9739836.html】,謝謝!

       筆者從事Anroid開發有些年頭了,深知掌握Anroid性能優化方面的知識的必要性,這是一個程序員必須修煉的內功。在面試中,它是面試官的摯愛,在工作中,它是代碼質量的攔路虎,其重要性可見一斑。在團隊中,性能優化的工作又往往由經驗豐富的老師傅來完成,可見要做好性能優化,絕不是一件容易的事情。

       性能優化方面涉及的知識點比較廣,有理論基礎知識,也有實際操作技能,筆者將通過一系列的文章來進行整理,將主要包括Java虛擬機、內存分配、垃圾回收,android虛擬機、進程管理、內存優化、內存泄漏,常用內存分析及優化工具介紹等。由於筆者水平和經驗有限,也是在邊研究邊整理,有不當之處,請不吝賜教。

前言

        之所以第一篇要先介紹JVM,是因爲當前Android開發的主流語言是java,而JVM又是java程序進程生命誕生的地方。JVM就像盤古一樣開天闢地,在機器上開闢了一個虛擬的空間,然後纔有了java生存的土壤。JVM也是中高級程序員,架構師,系統調優師等職位所必須要了解甚至深入掌握的知識點。當然,本系列的重點是內存及性能上的優化,所以本文只對JVM做一定概略性的講解,不做太深入的研究。本文主要內容如下:

                       

一、什麼是JVM?

       咱們這裏借鑑百度百科的解釋:

       JVM是Java Virtual Machine 的縮寫,即Java虛擬機,它是一種用於計算設備的規範,通過在實際的計算機上仿真模擬各種計算機功能來實現,可以簡單理解爲,它是一個在實際計算機中虛構出來的寄生計算機。Java源文件經過編譯器編譯成.class文件(字節碼文件)後,由JVM來執行。JVM擁有一套支持java字節碼文件(.class文件)執行的環境,可以將.class文件解釋成具體平臺上的機器指令並執行。Java程序只需要生成.class文件,即可以在任何裝有JVM的設備上運行,而不需要理會具體操作系統平臺相關的信息。此時的JVM就像一個翻譯官一樣連接連接着.class文件和系統平臺。Java的這個特性叫做平臺無關性,實現了“一次編譯,到處運行”,JVM就是實現Java這個功能的大功臣。

 

二、JDK,JRE,JVM是什麼關係?

       如下截圖爲JDK安裝包結構

        

  1、JDK

      Java Development Kit 的縮寫,即 Java開發工具包,提供了開發java程序所需要的基本條件。在上圖JDK安裝包截圖的紅色邊框中

  • bin:最主要包含了編輯器javac.exe,功能是將java源文件編譯爲.class文件。
  • include:包含了Java和JVM交互用的頭文件。
  • lib:包含了java開發所需的類庫。
  • jre:爲Java運行環境。

  2、JRE

       Java Runtime Environment的縮寫,即Java運行環境,下圖爲JRE文件夾的內容。注意,JRE是運行環境,而不是開發環境。

      

  • bin:可以理解爲JVM,其中javaw.exe或java.exe用於執行.class文件。
  • lib:提供了JVM執行所需要的庫。

  3、JVM

        執行.class文件。

  4、結論

        這三者的關係可以通過下圖(摘自某網站)來理解:JDK包含了JRE,JRE又包含了JVM(對於比較懶得童鞋,可以先記住這個結論)。圖中提到的Java開發工具,集成有類庫和編譯工具,只需關聯jre即可。                

 

三、JVM的工作

  1、Java文件執行流程圖

       下圖顯示了JVM在java程序工作流中的位置,可以結合前面的內容來看。

    

  2、JVM實際工作內容

      實際上JVM的執行過程中,主要做了三個工作:

    (1)加載並執行.class文件;

    (2)管理並分配內存(推薦閱讀:【朝花夕拾】Android性能篇之(二)Java內存分配);

    (3)執行垃圾回收(推薦閱讀:【朝花夕拾】Android性能篇之(三)Java內存回收)。

 

四、JVM生命週期

       一個JVM實例對應一個獨立運行的Java程序,是屬於進程級別的,也有自己的生命週期:

  1、啓動

        當啓動一個Java程序的時候,就產生了一個JVM實例。我們還記得Java的入口函數 public static void main(String[] args)嗎?每個擁有該函數的.class都可以作爲JVM實例運行的起點。

  2、運行

        main()作爲起點,啓動主線程,其他任何線程都在該線程中啓動。JVM有兩種線程:User Thread(用戶線程)和Daemon Thread(守護線程:爲用戶線程服務的線程),main()線程爲用戶線程,而守護線程通常由JVM自己使用。

  3、消亡

        當程序中的所有用戶線程都終止時,JVM纔會退出,守護線程無線程需要服務了,也就跟着退出了歷史的舞臺。若安全管理器允許,程序也可以使用Runtime或者System.exit()來退出。

 

五、JVM架構及工作原理

       

       上圖更詳細地展示了JVM的架構,由圖可知,JVM主要是劃分爲三個子系統 :(1)類加載器子系統 (2)運行時數據區 (3)執行引擎 和Java本地接口、本地方法庫。

  1、類加載子系統(Class Loader SubSystem)

       Java的動態類加載功能由該子系統處理,當它在運行時(不是編譯時)首次引用一個類時,它加載、鏈接並初始化該類文件(.class文件)。

    (1)加載(Loading)

        類的加載在此組件中完成,加載過程主要由下面三個加載器實現:

        1)啓動類加載器(BootStrap class Loader)。負責從啓動類路徑中加載類,無非就是rt.jar。這個加載器會被賦予最高優先級。

        2)擴展類加載器(Extension class Loader)。負責加載ext目錄(jre\lib)內的類。

        3)應用程序類加載器(Application class Loader)。負責加載應用程序級別類路徑,涉及到路徑的環境變量等。

        這三個類加載器會遵循委託層次算法(Delegation Hierarchy Algorithm)加載類文件。

    (2)鏈接(Linking)

        該過程主要完成以下三個步驟:

        1)校驗(Verify)。字節碼校驗器會校驗生成的字節碼是否正確,如果校驗失敗,我們會得到校驗錯誤。

        2)準備(Prepare)。分配內存並初始化默認值給所有的靜態變量。

        3)解析(Resolve)。所有符號內存引用被方法區(Method Area)的原始引用所替代。

    (3)初始化(Initialization)

       這是類加載的最後階段,這裏所有的靜態變量會賦初始值,並且靜態塊將被執行。

  2、運行時數據區(Runtime Data Area)

       該部分將在後續的文章(【朝花夕拾】Android性能篇之(二)Java內存分配)中詳細講述,這裏不做贅述。

  3、執行引擎(Execution Engine)。

        分配給運行時數據區的字節碼將由執行引擎執行,執行引擎讀取字節碼並逐段執行。它包含了如下三個部分:解釋器、編譯器、垃圾回收器。

    (1)解釋器(interpreter)。

        解釋器能夠快速地解釋字節碼,但執行卻很慢。它的一個缺點就是,當一個方法被調用多次,每次都需要重新解釋。

    (2)JIT編譯器。

        JIT編譯器消除了解釋器的缺點,執行引擎利用解釋器轉換字節碼,但如果是重複的代碼,則使用JIT編譯器將全部字節碼編譯成本機代碼,本機代碼將直接用於重複的方法調用,這樣提高了系統的性能。它的工作由下面4個工具協同完成:

        1)中間代碼生成器。負責生成中間代碼。

        2)代碼優化器。負責優化上面生成的中間代碼。

        3)目標代碼生成器。負責生成機器代碼或本機代碼。

        4)探測器(Profiler)。一個特殊的組件,負責尋找被多次調用的方法。

    (3)垃圾回收器。

       蒐集並刪除未引用的對象。可以通過調用“System.gc()”來觸發垃圾回收,但並不保證會確實進行垃圾回收。JVM的垃圾回收只收集那些由new關鍵字創建的對象。所以,如果不是用new創建的對象,你可以使用finalize函數來執行清理。

  4、Java本地接口(JNI,Native Method Interface)

       JNI會與本地方法庫進行交互並提供執行引擎所需的本地庫。

  5、本地方法庫(Native Method Library)

      它是一個執行引擎的本地庫集合。 

 

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