乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      深入理解Java虛擬機(jī)到底是什么

       看風(fēng)景D人 2016-10-07

      什么是Java虛擬機(jī)


      作為一個(gè)Java程序員,我們每天都在寫(xiě)Java代碼,我們寫(xiě)的代碼都是在一個(gè)叫做Java虛擬機(jī)的東西上執(zhí)行的。但是如果要問(wèn)什么是虛擬機(jī),恐怕很多人就會(huì)模棱兩可了。在本文中,我會(huì)寫(xiě)下我對(duì)虛擬機(jī)的理解。因?yàn)槟芰λ蓿赡苡行┑胤矫枋龅牟粔蚯樊?dāng)。如果你有不同的理解,歡迎交流。

      我們都知道Java程序必須在虛擬機(jī)上運(yùn)行。那么虛擬機(jī)到底是什么呢?先看網(wǎng)上搜索到的比較靠譜的解釋?zhuān)?/p>

      虛擬機(jī)是一種抽象化的計(jì)算機(jī),通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。Java虛擬機(jī)有自己完善的硬體架構(gòu),如處理器、堆棧寄存器等,還具有相應(yīng)的指令系統(tǒng)。JVM屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息,使得Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。

      這種解釋?xiě)?yīng)該算是正確的,但是只描述了虛擬機(jī)的外部行為和功能,并沒(méi)有針對(duì)內(nèi)部原理做出說(shuō)明。一般情況下我們不需要知道虛擬機(jī)的運(yùn)行原理,只要專(zhuān)注寫(xiě)java代碼就可以了,這也正是虛擬機(jī)之所以存在的原因--屏蔽底層操作系統(tǒng)平臺(tái)的不同并且減少基于原生語(yǔ)言開(kāi)發(fā)的復(fù)雜性,使java這門(mén)語(yǔ)言能夠跨各種平臺(tái)(只要虛擬機(jī)廠(chǎng)商在特定平臺(tái)上實(shí)現(xiàn)了虛擬機(jī)),并且簡(jiǎn)單易用。這些都是虛擬機(jī)的外部特性,但是從這些信息來(lái)解釋虛擬機(jī),未免太籠統(tǒng)了,無(wú)法讓我們知道內(nèi)部原理。



      從進(jìn)程的角度解釋JVM


      讓我們嘗試從操作系統(tǒng)的層面來(lái)理解虛擬機(jī)。我們知道,虛擬機(jī)是運(yùn)行在操作系統(tǒng)之中的,那么什么東西才能在操作系統(tǒng)中運(yùn)行呢?當(dāng)然是進(jìn)程,因?yàn)檫M(jìn)程是操作系統(tǒng)中的執(zhí)行單位。可以這樣理解,當(dāng)它在運(yùn)行的時(shí)候,它就是一個(gè)操作系統(tǒng)中的進(jìn)程實(shí)例,當(dāng)它沒(méi)有在運(yùn)行時(shí)(作為可執(zhí)行文件存放于文件系統(tǒng)中),可以把它叫做程序。


      對(duì)命令行比較熟悉的同學(xué),都知道其實(shí)一個(gè)命令對(duì)應(yīng)一個(gè)可執(zhí)行的二進(jìn)制文件,當(dāng)敲下這個(gè)命令并且回車(chē)后,就會(huì)創(chuàng)建一個(gè)進(jìn)程,加載對(duì)應(yīng)的可執(zhí)行文件到進(jìn)程的地址空間中,并且執(zhí)行其中的指令。下面對(duì)比C語(yǔ)言和Java語(yǔ)言的HelloWorld程序來(lái)說(shuō)明問(wèn)題。


      首先編寫(xiě)C語(yǔ)言版的HelloWorld程序。

      1. #include <stdio.h>  
      2. #include <stdlib.h>  
      3.   
      4. int main(void) {  
      5.     printf("hello world\n");  
      6.     return 0;  
      7. }  

      編譯C語(yǔ)言版的HelloWorld程序:

      [plain] view plain copy
      在CODE上查看代碼片派生到我的代碼片
      1. gcc HelloWorld.c -o HelloWorld  

      運(yùn)行C語(yǔ)言版的HelloWorld程序:

      [plain] view plain copy
      在CODE上查看代碼片派生到我的代碼片
      1. zhangjg@linux:/deve/workspace/HelloWorld/src$ ./HelloWorld   
      2. hello world  

      gcc編譯器編譯后的文件直接就是可被操作系統(tǒng)識(shí)別的二進(jìn)制可執(zhí)行文件,當(dāng)我們?cè)诿钚兄星孟?./HelloWorld這條命令的時(shí)候, 直接創(chuàng)建一個(gè)進(jìn)程, 并且將可執(zhí)行文件加載到進(jìn)程的地址空間中, 執(zhí)行文件中的指令。


      作為對(duì)比, 我們看一下Java版HelloWord程序的編譯和執(zhí)行形式。


      首先編寫(xiě)源文件HelloWord.java :

      1. public class HelloWorld {  
      2.   
      3.     public static void main(String[] args) {  
      4.         System.out.println("HelloWorld");  
      5.     }  
      6. }  

      編譯Java版的HelloWorld程序:

      1. zhangjg@linux:/deve/workspace/HelloJava/src$ javac HelloWorld.java   
      2. zhangjg@linux:/deve/workspace/HelloJava/src$ ls  
      3. HelloWorld.class  HelloWorld.java  

      運(yùn)行Java版的HelloWorld程序:

      [plain] view plain copy
      在CODE上查看代碼片派生到我的代碼片
      1. zhangjg@linux:/deve/workspace/HelloJava/src$ java -classpath . HelloWorld   
      2. HelloWorld  

      從上面的過(guò)程可以看到, 我們?cè)谶\(yùn)行Java版的HelloWorld程序的時(shí)候, 敲入的命令并不是 ./HelloWorld.class 。 因?yàn)閏lass文件并不是可以直接被操作系統(tǒng)識(shí)別的二進(jìn)制可執(zhí)行文件 。 我們敲入的是java這個(gè)命令。 這個(gè)命令說(shuō)明, 我們首先啟動(dòng)的是一個(gè)叫做java的程序, 這個(gè)java程序在運(yùn)行起來(lái)之后就是一個(gè)JVM進(jìn)程實(shí)例。 


      上面的命令執(zhí)行流程是這樣的:

      java命令首先啟動(dòng)虛擬機(jī)進(jìn)程,虛擬機(jī)進(jìn)程成功啟動(dòng)后,讀取參數(shù)HelloWorld”,把他作為初始類(lèi)加載到內(nèi)存,對(duì)這個(gè)類(lèi)進(jìn)行初始化和動(dòng)態(tài)鏈接(關(guān)于類(lèi)的初始化和動(dòng)態(tài)鏈接會(huì)在后面的博客中介紹),然后從這個(gè)類(lèi)的main方法開(kāi)始執(zhí)行。也就是說(shuō)我們的.class文件不是直接被系統(tǒng)加載后直接在cpu上執(zhí)行的,而是被一個(gè)叫做虛擬機(jī)的進(jìn)程托管的。首先必須虛擬機(jī)進(jìn)程啟動(dòng)就緒,然后由虛擬機(jī)中的類(lèi)加載器加載必要的class文件,包括jdk中的基礎(chǔ)類(lèi)(如StringObject等),然后由虛擬機(jī)進(jìn)程解釋class字節(jié)碼指令,把這些字節(jié)碼指令翻譯成本機(jī)cpu能夠識(shí)別的指令,才能在cpu上運(yùn)行。


      從這個(gè)層面上來(lái)看,在執(zhí)行一個(gè)所謂的java程序的時(shí)候,真真正正在執(zhí)行的是一個(gè)叫做Java虛擬機(jī)的進(jìn)程,而不是我們寫(xiě)的一個(gè)個(gè)的class文件。這個(gè)叫做虛擬機(jī)的進(jìn)程處理一些底層的操作,比如內(nèi)存的分配和釋放等等。我們編寫(xiě)的class文件只是虛擬機(jī)進(jìn)程執(zhí)行時(shí)需要的原料。這些原料在運(yùn)行時(shí)被加載到虛擬機(jī)中,被虛擬機(jī)解釋執(zhí)行,以控制虛擬機(jī)實(shí)現(xiàn)我們java代碼中所定義的一些相對(duì)高層的操作,比如創(chuàng)建一個(gè)文件等,可以將class文件中的信息看做對(duì)虛擬機(jī)的控制信息,也就是一種虛擬指令。


      編程語(yǔ)言也有自己的原理, 學(xué)習(xí)一門(mén)語(yǔ)言, 主要是把它的原理搞明白。 看似一個(gè)簡(jiǎn)單的HelloWorld程序, 也有很多深入的內(nèi)容值得剖析。



      JVM體系結(jié)構(gòu)簡(jiǎn)介


      為了展示虛擬機(jī)進(jìn)程和class文件的關(guān)系,特意畫(huà)了下面一張圖:



      根據(jù)上圖表達(dá)的內(nèi)容,我們編譯之后的class文件是作為Java虛擬機(jī)的原料被輸入到Java虛擬機(jī)的內(nèi)部的,那么具體由誰(shuí)來(lái)做這一部分工作呢?其實(shí)在Java虛擬機(jī)內(nèi)部,有一個(gè)叫做類(lèi)加載器的子系統(tǒng),這個(gè)子系統(tǒng)用來(lái)在運(yùn)行時(shí)根據(jù)需要加載類(lèi)。注意上面一句話(huà)中的根據(jù)需要四個(gè)字。在Java虛擬機(jī)執(zhí)行過(guò)程中,只有他需要一個(gè)類(lèi)的時(shí)候,才會(huì)調(diào)用類(lèi)加載器來(lái)加載這個(gè)類(lèi),并不會(huì)在開(kāi)始運(yùn)行時(shí)加載所有的類(lèi)。就像一個(gè)人,只有餓的時(shí)候才去吃飯,而不是一次把一年的飯都吃到肚子里。一般來(lái)說(shuō),虛擬機(jī)加載類(lèi)的時(shí)機(jī),在第一次使用一個(gè)新的類(lèi)的時(shí)候。本專(zhuān)欄后面的文章會(huì)具體討論Java中的類(lèi)加載器。


      由虛擬機(jī)加載的類(lèi),被加載到Java虛擬機(jī)內(nèi)存中之后,虛擬機(jī)會(huì)讀取并執(zhí)行它里面存在的字節(jié)碼指令。虛擬機(jī)中執(zhí)行字節(jié)碼指令的部分叫做執(zhí)行引擎。就像一個(gè)人,不是把飯吃下去就完事了,還要進(jìn)行消化,執(zhí)行引擎就相當(dāng)于人的腸胃系統(tǒng)。在執(zhí)行的過(guò)程中還會(huì)把各個(gè)class文件動(dòng)態(tài)的連接起來(lái)。關(guān)于執(zhí)行引擎的具體行為和動(dòng)態(tài)鏈接相關(guān)的內(nèi)容也會(huì)在本專(zhuān)欄后續(xù)的文章中進(jìn)行討論。


      我們知道,Java虛擬機(jī)會(huì)進(jìn)行自動(dòng)內(nèi)存管理。具體說(shuō)來(lái)就是自動(dòng)釋放沒(méi)有用的對(duì)象,而不需要程序員編寫(xiě)代碼來(lái)釋放分配的內(nèi)存。這部分工作由垃圾收集子系統(tǒng)負(fù)責(zé)。


      從上面的論述可以知道, 一個(gè)Java虛擬機(jī)實(shí)例在運(yùn)行過(guò)程中有三個(gè)子系統(tǒng)來(lái)保障它的正常運(yùn)行,分別是類(lèi)加載器子系統(tǒng), 執(zhí)行引擎子系統(tǒng)和垃圾收集子系統(tǒng)。 如下圖所示:



      虛擬機(jī)的運(yùn)行,必須加載class文件,并且執(zhí)行class文件中的字節(jié)碼指令。它做這么多事情,必須需要自己的空間。就像人吃下去的東西首先要放在胃中。虛擬機(jī)也需要空間來(lái)存放個(gè)中數(shù)據(jù)。首先,加載的字節(jié)碼,需要一個(gè)單獨(dú)的內(nèi)存空間來(lái)存放;一個(gè)線(xiàn)程的執(zhí)行,也需要內(nèi)存空間來(lái)維護(hù)方法的調(diào)用關(guān)系,存放方法中的數(shù)據(jù)和中間計(jì)算結(jié)果;在執(zhí)行的過(guò)程中,無(wú)法避免的要?jiǎng)?chuàng)建對(duì)象,創(chuàng)建的對(duì)象需要一個(gè)專(zhuān)門(mén)的內(nèi)存空間來(lái)存放。關(guān)于虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的內(nèi)容,也會(huì)出現(xiàn)在本專(zhuān)欄后續(xù)的文章中。虛擬機(jī)的運(yùn)行時(shí)內(nèi)存區(qū)大概可以分成下圖所示的幾個(gè)部分。(這里只是大概劃分, 并沒(méi)有劃分的很精細(xì))



      總結(jié)


      寫(xiě)到這里,基本上關(guān)于我對(duì)java虛擬機(jī)的理解就寫(xiě)完了。這篇文章的主題雖然是深入理解Java虛擬機(jī),但是你可能感覺(jué)一點(diǎn)也不深入,也只是泛泛而談。我也有這樣的感覺(jué)。限于自己水平有限,也只能這樣了,要是想深入理解java虛擬機(jī),強(qiáng)烈建議讀一下三本書(shū):


      《深入Java虛擬機(jī)》

      《深入理解Java虛擬機(jī)JVM高級(jí)特性與最佳實(shí)踐》

      Java虛擬機(jī)規(guī)范》


      其實(shí)我也讀過(guò)這幾本書(shū),但是它們對(duì)虛擬機(jī)的解釋也是基于一個(gè)外部模型,而沒(méi)有深入剖析虛擬機(jī)內(nèi)部的實(shí)現(xiàn)原理。虛擬機(jī)是一個(gè)大而復(fù)雜的東西,實(shí)現(xiàn)虛擬機(jī)的人都是大牛級(jí)別的,如果不是參與過(guò)虛擬機(jī)的實(shí)現(xiàn),應(yīng)該很少有人能把它參透。本專(zhuān)欄后面的一些文章也參考了這三本書(shū), 雖然講解Java語(yǔ)法的書(shū)不計(jì)其數(shù), 但是深入講解虛擬機(jī)的書(shū), 目前為止我就見(jiàn)過(guò)這三本,并且網(wǎng)上的資料也不是很多。


      最后做一個(gè)總結(jié):

      虛擬機(jī)并不神秘,在操作系統(tǒng)的角度看來(lái),它只是一個(gè)普通進(jìn)程。

      這個(gè)叫做虛擬機(jī)的進(jìn)程比較特殊,它能夠加載我們編寫(xiě)的class文件。如果把JVM比作一個(gè)人,那么class文件就是我們吃的食物。

      加載class文件的是一個(gè)叫做類(lèi)加載器的子系統(tǒng)。就好比我們的嘴巴,把食物吃到肚子里。

      虛擬機(jī)中的執(zhí)行引擎用來(lái)執(zhí)行class文件中的字節(jié)碼指令。就好比我們的腸胃,對(duì)吃進(jìn)去的食物進(jìn)行消化。

      虛擬機(jī)在執(zhí)行過(guò)程中,要分配內(nèi)存創(chuàng)建對(duì)象。當(dāng)這些對(duì)象過(guò)時(shí)無(wú)用了,必須要自動(dòng)清理這些無(wú)用的對(duì)象。清理對(duì)象回收內(nèi)存的任務(wù)由垃圾收集器負(fù)責(zé)。就好比人吃進(jìn)去的食物,在消化之后,必須把廢物排出體外,騰出空間可以在下次餓的時(shí)候吃飯并消化食物。




      更多關(guān)于深入理解Java的文章, 請(qǐng)關(guān)注我的專(zhuān)欄 : http://blog.csdn.net/column/details/zhangjg-java-blog.html

      更多關(guān)于Java和Android等其他技術(shù)的文章, 請(qǐng)關(guān)注我的博客: http://blog.csdn.net/zhangjg_blog


        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多