對JVM的理解


操作系統內核是至高無尚的內功心法,只有掌握了內功,學習其他的武功才會輕而易舉。

現在我們來談談java。JVM其實是操作系統中運行的進程,JVM有操作系統進程的所有共性,但是它卻不是一個普通的進程,它有它特殊的地方,它將許多本來屬於操作系統管理范疇的東西,移植到了JVM內部,減少系統調用的開銷。

1.在普通程序(如C++)中,如果new一個對象,會產生一個系統調用,由操作系統線程根據對象的大小分配好空間后返回;若要釋放對象,也需要detele產生一個系統調用,通知操作系統 對象所占用的空間已經可以回收。但是JVM堆中,只需要在最開始進行一次系統調用,向操作系統申請一整段區域作為java程序的堆,之后創建和銷毀對象都不需要再進行系統調用,而是直接由JVM在內部按需分配,這樣大大減少了系統調用的開銷。同時C++需要明確調用delete進行內存回收,如果程序員忘了就很容易造成內存泄露,然而在JVM中有垃圾回收器負責回收內存。

2.應用程序通常不直接和內核內存打交道,內核內存由操作系統進行管理和使用;不過隨着Linux對性能的關注及改進,一些新的特性使得應用程序(JVM)可以使用內核內存,或者是映射到內核空間。Java NIO正是在這種背景下誕生的。在java NIO中,為了減少讀寫IO系統調用的開銷,使用到了內核的內存。當應用程序想將磁盤文件的數據發送網卡,不需要先進行系統調用讀入用戶空間,再系統調用輸出到內核空間,而是直接在內核空間就完成整個操作了,大大減少了系統調用的次數

 

 

我們可以把JVM看成一台虛擬的機器,這台機器可以按需加載可執行二進制文件(字節碼文件),然后由虛擬機執行引擎解釋執行字節碼,將其翻譯成cpu可以識別的指令。在jvm的邏輯地址空間中,有方法區(用來存放可執行文件),堆(用於存放對象和數組,jvm垃圾回收器動態分配和回收該區域的內存空間),棧(保存線程的方法調用關系,數據),常量池(存放常量)等。因此,一個Java虛擬機實例在運行過程中有三個子系統來保障它的正常運行,分別是類加載器子系統, 執行引擎子系統和垃圾收集子系統。字節碼文件相當於食物,類加載器相當於嘴,執行引擎相當於胃,垃圾回收器相當於排泄系統。    

執行引擎包括字節碼解釋器和JIT(just-in-time)及時編譯器,解釋器將字節碼文件一行一行邊解釋邊執行(解釋成cpu能識別的指令),而JIT編譯器則是將整個字節碼文件編譯成cpu能夠識別的指令,也就是在執行前全部被翻譯為機器碼,這樣做的好處是將熱點代碼緩存起來,下次使用的時候cpu直接執行,而不用再逐行解釋。

 

為什么要引入java虛擬機呢?是為了讓java能夠跨平台。

在c語言中,只需要gcc將源代碼文件編譯后,操作系統就可以識別該執行文件了。但是在java中,當編譯成字節碼文件后,操作系統是無法直接運行的,因為不識別,所以引入了JVM,由JVM負責加載字節碼文件,然后在JVM中解釋執行,將其翻譯成cpu可以識別的指令。這樣一來,只需要讓JVM平台相關就可以了,不同操作系統安裝對應版本的JVM,然后由JVM負責和操作系統打交道,從而讓java代碼變成平台無關的。只需要一次編譯,就能夠到處執行。

java HelloWorld,該命令會首先啟動一個虛擬機進程,將HelloWorld的可執行文件加載到該進程的地址空間,然后解釋執行。在Java虛擬機執行過程中,只有當需要一個類的時候,才會調用類加載器來加載這個類,並不會在開始運行時加載所有的類。這種類的動態加載機制造就了java的多態。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM