成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

深入淺析Java中JVM的原理-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)深入淺析Java中 JVM的原理,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)制作、網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)公司推出漯河免費(fèi)做網(wǎng)站回饋大家。

JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。Java虛擬機(jī)包括一套字節(jié)碼指令集、一組寄存器、一個(gè)棧、一個(gè)垃圾回收堆和一個(gè)存儲(chǔ)方法域。 JVM屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息,使Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。是運(yùn)行Java應(yīng)用最底層部分。

JDK(Java Development kit)

整個(gè)Java的核心,包括了Java運(yùn)行環(huán)境(Java Runtime Envirnment),一堆Java工具(編譯,debug等)和Java基礎(chǔ)的類庫(kù)(rt.jar)。是開發(fā)java應(yīng)用的基礎(chǔ)。

JRE(Java Runtime Environment,Java運(yùn)行環(huán)境)

運(yùn)行JAVA程序所必須的環(huán)境的集合,包含JVM標(biāo)準(zhǔn)實(shí)現(xiàn)及Java核心類庫(kù)。運(yùn)行java應(yīng)用的基礎(chǔ)。

J2SE(Java 2 Platform,Standard Edition)。

包含那些構(gòu)成Java語(yǔ)言核心的類。比如:數(shù)據(jù)庫(kù)連接、接口定義、輸入/輸出、網(wǎng)絡(luò)編程

J2EE(Java 2 Platform,Enterprise Edition)。

Enterprise Edition(企業(yè)版) J2EE 包含J2SE 中的類,并且還包含用于開發(fā)企業(yè)級(jí)應(yīng)用的類。比如:EJB、servlet、JSP、XML、事務(wù)控制。

主要JVM

首先,JVM是一套規(guī)范。很多公司均實(shí)現(xiàn)了各自的虛擬機(jī)。常見的有

HotSpot JVM(sun)
Jrockit JVM(BEA公司的JVM,應(yīng)用于weblogic)
IBM JVM
Apache Harmony

其中,我們常用的是HotSpot JVM.

JVM結(jié)構(gòu)

深入淺析Java中 JVM的原理

第一步(編譯):

創(chuàng)建完源文件之后,程序會(huì)先被編譯為.class文件。Java編譯一個(gè)類時(shí),如果這個(gè)類所依賴的類還沒有被編譯,編譯器就會(huì)先編譯這個(gè)被依賴的類,然后 引用,這個(gè)有點(diǎn)象make。如果java編譯器在指定目錄下找不到該類所其依賴的類的.class文件或者.java源文件的話,編譯器話 報(bào)“cant find symbol”的錯(cuò)誤。

第二步(運(yùn)行):

Java類運(yùn)行的過程大概可分為兩個(gè)過程:1、類的加載  2、類的執(zhí)行。

需要說明的是:JVM主要在程序第一次主動(dòng)使用類的時(shí)候,才會(huì)去加載該類。也就是說,JVM并不是在一開始就把一個(gè)程序就所有的類都加載到內(nèi)存中,而是到不得不用的時(shí)候才把它加載進(jìn)來,而且只加載一次。

1、 在 編譯好java程序得到MainApp.class文件后,在命令行上敲java AppMain。系統(tǒng)就會(huì)啟動(dòng)一個(gè)jvm進(jìn)程,jvm進(jìn)程從classpath路徑中找到一個(gè)名為AppMain.class的二進(jìn)制文件,將 MainApp的類信息加載到運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),這個(gè)過程叫做MainApp類的加載。

2、 (java命令)然后JVM找到AppMain的主函數(shù)入口,開始執(zhí)行main函數(shù)

3、 (類加載器)執(zhí)行過程中,會(huì)創(chuàng)建對(duì)象。JVM會(huì)首先從方法區(qū)加載類信息和相關(guān)常量,class加載完畢之后,在堆上為對(duì)象分配內(nèi)存,然后調(diào)用初始化實(shí)例,當(dāng)然這時(shí)候?qū)嵗3种赶騝lass類型信息,這個(gè)信息保存在方法區(qū)中。

4、 (執(zhí)行引擎)調(diào)用實(shí)例方法時(shí),會(huì)根據(jù)引用找到對(duì)象信息,進(jìn)而可定位對(duì)應(yīng)的class類型信息,和方法表。

5、 (執(zhí)行引擎)執(zhí)行方法時(shí),在虛擬機(jī)棧中進(jìn)行,分配棧幀,隨著入棧出棧,完成方法調(diào)用操作。

執(zhí)行引擎

運(yùn)行Java的每一個(gè)線程都是一個(gè)獨(dú)立的虛擬機(jī)執(zhí)行引擎的實(shí)例。從線程生命周期的開始到結(jié)束,他要么在執(zhí)行字節(jié)碼,要么在執(zhí)行本地方法。一個(gè)線程可能通過解釋或者使用芯片級(jí)指令直接執(zhí)行字節(jié)碼,或者間接通過JIT執(zhí)行編譯過的本地代碼。我們上文講到的main函數(shù),也就是執(zhí)行引擎的操作入口。

Class文件

實(shí)際上,Class文件中方法的字節(jié)碼流就是有JVM的指令序列構(gòu)成的。每一條指令包含一個(gè)單字節(jié)的操作碼,后面跟隨0個(gè)或多個(gè)操作數(shù)。

iload_0    // 把存儲(chǔ)在局部變量區(qū)中索引為0的整數(shù)壓入操作數(shù)棧。
iload_1    // 把存儲(chǔ)在局部變量區(qū)中索引為1的整數(shù)壓入操作數(shù)棧。
iadd         // 從操作數(shù)棧中彈出兩個(gè)整數(shù)相加,在將結(jié)果壓入操作數(shù)棧。
istore_2   // 從操作數(shù)棧中彈出結(jié)果

JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)

1)程序計(jì)數(shù)器(線程私有)

當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,通過改變這個(gè)計(jì)數(shù)器的值,確定下一條要執(zhí)行的命令。分支,循環(huán),跳轉(zhuǎn)都需要它的支持。

它是線程私有的,每個(gè)線程都有專屬于自己的程序記數(shù)器,線程之間互不影響,獨(dú)立存儲(chǔ),保證了線程切換后,可以恢復(fù)到原先執(zhí)行位置。

2)Java虛擬機(jī)棧(線程私有)

每個(gè)方法的執(zhí)行,同時(shí)都會(huì)在虛擬機(jī)棧上創(chuàng)建一個(gè)棧幀。用于存儲(chǔ)局部變量表,操作數(shù)棧,方法出口,動(dòng)態(tài)鏈接等。一個(gè)方法的執(zhí)行周期,同時(shí)也就對(duì)應(yīng)著棧幀的出棧入棧操作。有時(shí)候方法的遞歸,會(huì)造成大量的棧幀,達(dá)到一定的深度,會(huì)報(bào)StackOverflowError異常。有一點(diǎn)需要說明:在編譯器編譯Java代碼時(shí),就已經(jīng)在字節(jié)碼中為每個(gè)方法都設(shè)置好了局部變量區(qū)和操作數(shù)棧的數(shù)據(jù)和大小。并在JVM首次加載方法所屬的Class文件時(shí), 就將這些數(shù)據(jù)放進(jìn)了方法區(qū)。因此在線程調(diào)用方法時(shí),只需要根據(jù)方法區(qū)中的局部變量區(qū)和操作數(shù)棧的大小來分配一個(gè)新的棧幀的內(nèi)存大小,并堆入Java棧。

局部變量區(qū): 用來存放方法中的所有局部變量值,包括傳遞的參數(shù)。這些數(shù)據(jù)會(huì)被組織成以一個(gè)字長(zhǎng)(32bit或64bit)為單位的數(shù)組結(jié)構(gòu)(以索引0開始)中。其中類 型為int, float, reference(引用類型,記錄對(duì)象在堆中地址)和returnAddress(一種JVM內(nèi)部使用的基本類型)的值占用1個(gè)字長(zhǎng),而byte, char和shot會(huì)擴(kuò)大成1個(gè)字長(zhǎng)存儲(chǔ),long,double則使用2個(gè)字長(zhǎng)。

 操作數(shù)棧: 用來在執(zhí)行指令的時(shí)候存儲(chǔ)和使用中間結(jié)果數(shù)據(jù)。

幀數(shù)據(jù)區(qū): 常量池的解析,正常方法返回以及異常派發(fā)機(jī)制的信息數(shù)據(jù)都存儲(chǔ)在其中。

3)本地方法棧(線程私有)

與Java虛擬機(jī)棧類似,只不過該區(qū)域是為native方法提供服務(wù)。

4)方法區(qū)(Perm)(線程共享)

    存儲(chǔ)已被虛擬機(jī)加載的類信息,常量,靜態(tài)變量,即時(shí)編譯后的代碼等數(shù)據(jù)。包含運(yùn)行時(shí)常量池,用于存放編譯器生成的各種字面量和符號(hào)引用,這部分內(nèi)容是在類加載后進(jìn)入方法區(qū)運(yùn)行時(shí)常量池中。

5)堆

深入淺析Java中 JVM的原理

堆是整個(gè)內(nèi)存數(shù)據(jù)區(qū)最負(fù)責(zé)的部分,負(fù)責(zé)對(duì)象的創(chuàng)建。同時(shí),垃圾回收的主要工作也在于此。堆又進(jìn)一步進(jìn)行細(xì)分,主要是為了滿足垃圾回收。

堆的組成

Eden(伊甸園):對(duì)象創(chuàng)建的入口。

Survivor Space:用于保存在eden space內(nèi)存池中經(jīng)過垃圾回收后沒有被回收的對(duì)象,也就是“幸存還活著”的對(duì)象。

幸存者0區(qū)(Survivor 0 space)和幸存者1區(qū)(Survivor1 space):當(dāng)伊甸園的空間用完時(shí),程序又需要?jiǎng)?chuàng)建對(duì)象;此時(shí)JVM的垃圾回收器將對(duì)伊甸園區(qū)進(jìn)行垃圾回收,將伊甸園區(qū)中的不再被其他對(duì)象所引用的對(duì)象 進(jìn)行銷毀工作。同時(shí)將伊甸園中的還有其他對(duì)象引用的對(duì)象移動(dòng)到幸存者0區(qū)。幸存者0區(qū)就是用于存放伊甸園垃圾回收時(shí)所幸存下來的JAVA對(duì)象。

當(dāng)將伊甸園中的還有其他對(duì)象引用的對(duì)象移動(dòng)到幸存者0區(qū)時(shí),如果幸存者0區(qū)也沒有空間來存放這些對(duì)象時(shí),JVM的垃圾回收器將對(duì)幸存者0區(qū)進(jìn)行垃圾 回收處理,將幸存者0區(qū)中不在有其他對(duì)象引用的JAVA對(duì)象進(jìn)行銷毀,將幸存者0區(qū)中還有其他對(duì)象引用的對(duì)象移動(dòng)到幸存者1區(qū)。幸存者1區(qū)的作用就是用于 存放幸存者0區(qū)垃圾回收處理所幸存下來的JAVA對(duì)象。

Tenured :對(duì)象經(jīng)過survivor 1 space內(nèi)存池,每經(jīng)歷過一次垃圾回收,年齡就增加1,超過設(shè)定閥值后,被移入終身代,當(dāng)然也包括由于擔(dān)保機(jī)制移入的對(duì)象。對(duì)于新生代和老年代,垃圾回收器對(duì)其態(tài)度不同。發(fā)生在新生代的回收頻率頻繁,大部分對(duì)象是“朝生夕死”,收集算法一般采用高效簡(jiǎn)單的復(fù)制算法,也就是上文描述的對(duì)象轉(zhuǎn)移操作(Eden->survivor 0,survivor 0->survivor 1)。發(fā)生在該區(qū)域的垃圾回收為Young GC.對(duì)于老年代,由于大部分對(duì)象主要為存活率高的對(duì)象,垃圾回收器采用”標(biāo)記-整理“算法。發(fā)生在該區(qū)域的垃圾回收為FULL GC.

堆相關(guān)參數(shù)

(影響堆空間劃分,進(jìn)而會(huì)影響GC發(fā)生頻率)JVM調(diào)優(yōu)工作,主要是基于這些參數(shù),進(jìn)行適當(dāng)調(diào)整管理,達(dá)到調(diào)整堆內(nèi)存大小及比例大小,以滿足實(shí)際業(yè)務(wù)需求。另外還包括方法區(qū)。

-Xms:設(shè)置 Java 應(yīng)用程序啟動(dòng)時(shí)的初始堆大小;
-Xmx:設(shè)置 Java 應(yīng)用程序能獲得的大堆大??;
-Xss:設(shè)置線程棧的大??;
-XX:MinHeapFreeRatio:設(shè)置堆空間最小空閑比例。當(dāng)堆空間的空閑內(nèi)存小于這個(gè)數(shù)值時(shí),JVM 便會(huì)擴(kuò)展堆空間;
-XX:MaxHeapFreeRatio:設(shè)置堆空間的大空閑比例。當(dāng)堆空間的空閑內(nèi)存大于這個(gè)數(shù)值時(shí),便會(huì)壓縮堆空間,得到一個(gè)較小的堆;
-XX:NewSize:設(shè)置新生代的大?。?br/>-XX:NewRatio:設(shè)置老年代與新生代的比例,它等于老年代大小除以新生代大?。?br/>-XX:SurvivorRatio:新生代中 eden 區(qū)與 survivor 區(qū)的比例;
-XX:MaxPermSize:設(shè)置大的持久區(qū)大?。?br/>-XX:TargetSurvivorRatio: 設(shè)置 survivor 區(qū)的可使用率。當(dāng) survivor 區(qū)的空間使用率達(dá)到這個(gè)數(shù)值時(shí),會(huì)將對(duì)象送入老年代。

對(duì)象的生命周期

  創(chuàng)建階段

1、檢查指令的參數(shù),是否能在常量池中定位到一個(gè)類的符號(hào)引用,如果是引用,判斷代表的類是否加載,解析和初始化過

2、如果沒有加載,則必須進(jìn)行加載,解析和初始化

3、類加載檢查,這時(shí)候已經(jīng)知道所需內(nèi)存的大小。

4、分配內(nèi)存。從java堆中劃分一塊大小確定的內(nèi)存。支持2種方式,至于選擇哪種方式分配內(nèi)存,與java堆是否規(guī)整有關(guān)(也就是是否空間空間和使用空間相互交錯(cuò)情況)。1.指針碰撞(分界點(diǎn)的指示器移動(dòng));2.空閑列表方式。然而,java堆是否規(guī)整,則取決于垃圾收集器的工作方式。此外,在分配內(nèi)存時(shí)還要考慮多線程情況,保證原子性。分配內(nèi)存的原子性有2種方式進(jìn)行保證(CAS 和 本地線程分配緩沖-XX +/- UseTLAB)。

5)、分配內(nèi)存完成后,初始化內(nèi)存空間(初始化為0)

6、維護(hù)對(duì)象的對(duì)象頭信息。如元數(shù)據(jù)信息,哈希碼,GC分代年齡,鎖信息,類元指針。

7、調(diào)用init方法,按照程序員意愿進(jìn)行初始化。

     <7.1> 從超類到子類對(duì)static成員進(jìn)行初始化;
     <7.2> 超類成員變量按順序初始化,遞歸調(diào)用超類的構(gòu)造方法;
      <7.3> 子類成員變量按順序初始化,子類構(gòu)造方法調(diào)用。

應(yīng)用階段

分為強(qiáng)引用、軟引用、虛引用、若引用

   不可視階段;

當(dāng)一個(gè)對(duì)象處于不可視階段,說明我們?cè)谄渌麉^(qū)域的代碼中已經(jīng)不可以在引用它,其強(qiáng)引用已經(jīng)消失,例如,本地變量超出了其可視的范圍。

   不可到達(dá)階段;

處于JVM對(duì)象生命周期不可到達(dá)階段的對(duì)象,在虛擬機(jī)所管理的對(duì)象引用根集合中再也找不到直接或間接的強(qiáng)引用,這些對(duì)象通常是指所有線程棧中的臨時(shí)變量, 所有已裝載的類的靜態(tài)變量或者對(duì)本地代碼接口(JNI)的引用。這些對(duì)象都是要被垃圾回收器回收的預(yù)備對(duì)象,但此時(shí)該對(duì)象并不能被垃圾回收器直接回收。其 實(shí)所有垃圾回收算法所面臨的問題是相同的——找出由分配器分配的,但是用戶程序不可到達(dá)的內(nèi)存塊。

   可收集階段、終結(jié)階段、釋放階段 ;

當(dāng)一個(gè)對(duì)象處于可收集階段、終結(jié)階段與釋放階段時(shí)

<1> 回收器發(fā)現(xiàn)該對(duì)象已經(jīng)不可達(dá)。 

     <2> finalize方法已經(jīng)被執(zhí)行。 

     <3> 對(duì)象空間已被重用。

關(guān)于深入淺析Java中 JVM的原理就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)站欄目:深入淺析Java中JVM的原理-創(chuàng)新互聯(lián)
分享地址:http://jinyejixie.com/article44/dijche.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、品牌網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣、ChatGPT網(wǎng)站設(shè)計(jì)公司、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
南宁市| 会昌县| 华亭县| 牙克石市| 巴彦淖尔市| 萨迦县| 忻州市| 衡阳市| 孟州市| 甘谷县| 莱阳市| 忻州市| 隆林| 那坡县| 新乡市| 杭锦旗| 鹤庆县| 湘乡市| 博乐市| 宾阳县| 大厂| 台湾省| 景德镇市| 绿春县| 嵊州市| 沙坪坝区| 开鲁县| 温州市| 武宣县| 碌曲县| 深州市| 张家港市| 民乐县| 尉犁县| 静海县| 岳普湖县| 交口县| 伊宁县| 合江县| 湖州市| 宜兰县|