最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

分析JVM的組成結(jié)構(gòu)

 更新時間:2021年06月23日 10:03:56   作者:IT王小二  
JVM(虛擬機):指以軟件的方式模擬具有完整硬件系統(tǒng)功能、運行在一個完全隔離環(huán)境中的完整計算機系統(tǒng) ,是物理機的軟件實現(xiàn)。JVM和VMware,Virtual Box等虛擬機一樣,都是運行在操作系統(tǒng)之上的計算機系統(tǒng)

一、JavaSE體系

  • JavaSE,Java 平臺標準版,為 Java EE 和 Java ME 提供了基礎(chǔ)。
  • JDK:Java 開發(fā)工具包,JDK 是 JRE 的超集,包含 JRE 中的所有內(nèi)容,以及開發(fā)程序所需的編譯器和調(diào)試程序等工具。
  • JRE:Java SE 運行時環(huán)境 ,提供庫、Java 虛擬機和其他組件來運行用 Java 編程語言編寫的程序。主要類庫,包括:程序部署發(fā)布、用戶界面工具類、繼承庫、其他基礎(chǔ)庫,語言和工具基礎(chǔ)庫。
  • JVM:Java 虛擬機,負責 JavaSE 平臺的硬件和操作系統(tǒng)無關(guān)性、編譯執(zhí)行代碼(字節(jié)碼)和平臺安全性。

二、運行時數(shù)據(jù)區(qū)

  • 線程私有:程序計數(shù)器、虛擬機棧、本地方法棧。
  • 線程共享:堆、方法區(qū)。

三、程序計數(shù)器

3.1、什么是程序計數(shù)器

程序計數(shù)器是一塊較小的內(nèi)存空間,它的作用可以看作是當前線程所執(zhí)行的字節(jié)碼的行號指示器。在虛擬機的概念模型里字節(jié)碼解釋器工作時就是通過改變這個計數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個計數(shù)器來完成。 -- 摘自《深入理解Java虛擬機》

3.2、程序計數(shù)器有什么特點

  • 程序計數(shù)器會隨著線程的啟動而創(chuàng)建,各線程之間獨立存儲,互不影響。
  • 當前線程執(zhí)行的字節(jié)碼的行號指示器。
  • 如果線程正在執(zhí)行的是一個 Java 方法,則指明當前線程執(zhí)行的代字節(jié)碼行數(shù)。
  • 如果正在執(zhí)行的是 Natvie 方法(本地方法),這個計數(shù)器值則為空(Undefined)。
  • 占用較小的內(nèi)存空間,此內(nèi)存區(qū)域是唯一一個不會出現(xiàn) OutOfMemoryError(內(nèi)存溢出) 情況的區(qū)域。

3.3、用個例子來說明

請無視我文章中取得類名,為了方便實驗演示,命名怎么快怎么來。

public class Jvm1 {

    public int test(){
        int a = 100;
        int b = 200;
        return a + b;
    }
}

這樣一個類, javac Jvm1.java,編譯成Jvm1.class文件。

再使用 javap 反匯編工具javap -c Jvm1.class看下.class文件中數(shù)據(jù)格式。

這個就是前面提到的 當前線程執(zhí)行的字節(jié)碼的行號,而程序計數(shù)器則記錄的這個數(shù)字。

  • 當然這也解釋了程序計數(shù)器不存在 OutOfMemoryError 的原因,因為它記錄的只是數(shù)字,占用空間少。
  • 同時也解釋了為什么執(zhí)行的是一個 Java 方法時,則指明當前線程執(zhí)行的代字節(jié)碼行數(shù)。
  • 而執(zhí)行 native方法 時程序計數(shù)器為 Undefined,因為 native方法 是大多是通過C實現(xiàn)并未編譯成需要執(zhí)行的字節(jié)碼指令,所以在計數(shù)器中當然是空。

四、虛擬機棧

  • 棧有什么特點? 先進后出。
  • 虛擬機棧是每個線程私有的,線程在運行時,在執(zhí)行每個方法的時候都會打包成一個 棧幀,存儲了 局部變量表,操作數(shù)據(jù)棧,動態(tài)鏈接,方法出口等信息,然后放入棧。每個時刻正在執(zhí)行的當前方法就是虛擬機棧頂?shù)臈E。方法的執(zhí)行就對應(yīng)著棧幀在虛擬機棧中入棧和出棧的過程。
  • 棧的大小缺省為 1M,可用參數(shù) –Xss 調(diào)整大小,例如-Xss256k。

一個例子來看看執(zhí)行 每個方法入棧出棧 的過程。

public class Jvm2 {

    public static void main(String[] args) {
        A();
    }

    public static void A() {
        System.out.println("A開始");
        // 此處省略100行代碼
        B(); // 調(diào)用B方法
        System.out.println("A結(jié)束");
    }

    public static void B() {
        System.out.println("B開始");
        // 此處省略100行代碼
        C(); // 調(diào)用B方法
        System.out.println("B結(jié)束");
    }

    public static void C() {
        System.out.println("C開始");
        // 此處省略100行代碼
        System.out.println("C結(jié)束");
    }
}

輸出:

A開始

B開始

C開始

C結(jié)束

B結(jié)束

A結(jié)束

4.1、局部變量表

  • 顧名思義就是局部變量的表,用于存放我們的局部變量的。
  • 主要存放我們的 Java 的八大基礎(chǔ)數(shù)據(jù)類型,如果是局部的一些對象,比如我們的 Object 對象,我們只需要存放它的一個引用地址即可。(基本數(shù)據(jù)類型、對象引用、returnAddress 類型)。

4.2、操作數(shù)據(jù)棧

  • 存放我們方法執(zhí)行的操作數(shù)的,它就是一個棧,先進后出的棧結(jié)構(gòu)。
  • 操作數(shù)棧,就是用來操作的,操作的的元素可以是任意的 java 數(shù)據(jù)類型。
  • 所以我們知道一個方法剛剛開始的時候,這個方法的操作數(shù)棧就是空的,操作數(shù)棧運行方法是會一直運行入棧/出棧的操作。

數(shù)據(jù)重疊優(yōu)化

虛擬機概念模型中每二個棧幀都是相互獨立的,但在實際應(yīng)用是我們知道一個方法調(diào)用另一個方法時,往往存在參數(shù)傳遞,這種做法在虛擬機實現(xiàn)過程中會做一些優(yōu)化,具體做法如下:令兩個棧幀出現(xiàn)一部分重疊。讓下面棧幀的一部分操作數(shù)棧與上面棧幀的部分局部變量表重疊在一起,進行方法調(diào)用時就可以共用一部分數(shù)據(jù),無須進行額外的參數(shù)復(fù)制傳遞。

4.3、動態(tài)鏈接

需要類加載、運行時才能確定具體的方法。

棧幀中會持有一個引用(符號引用),該引用指向某個具體方法。

符號引用是一個地址位置的代號,在編譯的時候我們是不知道某個方法在運行的時候是放到哪里的,這時我用代號 com/enjoy/pojo/User.Say:()V 指代某個類的方法,將來可以把符號引用轉(zhuǎn)換成直接引用進行真實的調(diào)用。用符號引用轉(zhuǎn)化成直接引用的解析時機,把解析分為兩大類:

  • 靜態(tài)解析:符號引用在類加載階段或者第一次使用的時候就直接轉(zhuǎn)換成直接引用。
  • 動態(tài)連接:符號引用在每次運行期間轉(zhuǎn)換為直接引用,即每次運行都重新轉(zhuǎn)換。

4.4、方法出口

1、正常返回(調(diào)用程序計數(shù)器中的地址作為返回)三步曲

  • 恢復(fù)上層方法的局部變量表和操作數(shù)棧
  • 把返回值(如果有的話)壓入調(diào)用者棧幀的操作數(shù)棧中
  • 調(diào)整 PC 計數(shù)器的值以指向方法調(diào)用指令后面的一條指令

2、異常返回

指方法執(zhí)行過程中遇到異常,并且這個異常在方法體內(nèi)部沒有得到處理,導(dǎo)致方法退出

4.5、棧溢出

  • java.lang.StackOverflowError:一般的方法調(diào)用是很難出現(xiàn)的,如果出現(xiàn)了要考慮是否有 無限遞歸 ,虛擬機棧帶給我們的啟示:方法的執(zhí)行因為要打包成棧楨,所以天生要比實現(xiàn)同樣功能的循環(huán)慢,所以樹的遍歷算法中:遞歸和非遞歸(循環(huán)來實現(xiàn))都有存在的意義。遞歸代碼簡潔,非遞歸代碼復(fù)雜但是速度較快。
  • OutOfMemoryError:不斷建立線程(一般演示不出,演示出來機器也死了)。

五、本地方法棧

  • 本地方法棧和虛擬機棧所發(fā)揮的作用是非常相似的,其區(qū)別不過是虛擬機棧為虛擬機執(zhí)行 Java 方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機使用到的 Native 方法服務(wù)。
  • 虛擬機規(guī)范中對本地方法棧中的方法使用的語言、使用方式與數(shù)據(jù)結(jié)構(gòu)并沒有強制規(guī)定,因此具體的虛擬機可以自由實現(xiàn)它。
  • 本地方法棧 native 方法通過 JNI 調(diào)用到了底層的 C/C++(c/c++可以觸發(fā)匯編語言,然后驅(qū)動硬件)。
  • 當一個JVM創(chuàng)建的線程調(diào)用native方法后,JVM不再為其在虛擬機棧中創(chuàng)建棧幀,JVM只是簡單地動態(tài)鏈接并直接調(diào)用native方法。

六、方法區(qū)

主要存儲類信息、常量池、靜態(tài)變量、即時編譯期編譯后的代碼等數(shù)據(jù)。

永久代和元空間:

方法區(qū)在 jdk1.7 及其之前又背稱為永久代,jdk1.8 又被稱為元空間,怎么理解呢?

1.jdk1.8移除了永久代,新增了元空間。

2.可以理解為方法區(qū)是一個規(guī)范,但是具體怎么實現(xiàn)要看具體的jvm怎么實現(xiàn)。

3.就類似于提供了一個接口方法(規(guī)范),只要實現(xiàn)了這個接口的類,那么就要去實現(xiàn)里面接口方法(具體實現(xiàn)就是各種版本jvm之間和版本之間的差異了)。

4.各種版本jvm 。

  • HotSpot VM(SUN) 以前使用范圍最廣的Java虛擬機。
  • JRockit VM(BEA) 號稱世界上最快的JVM 。
  • Dalvik VM(Google) google自己開發(fā)的。
  • HotSPont VM(ORACLE) 目前以前使用范圍最廣的Java虛擬機。

5.版本差異(jdk1.7, jdk1.8) 。

參數(shù)設(shè)置:

  • jdk1.7 及以前:-XX:PermSize;-XX:MaxPermSize;
  • jdk1.8 以后:-XX:MetaspaceSize; -XX:MaxMetaspaceSize
  • jdk1.8 以后大小就只受本機總內(nèi)存的限制

七、堆

  • 幾乎所有對象都分配在堆內(nèi)存,也是垃圾回收發(fā)生的主要區(qū)域。
  • 堆內(nèi)存由多個線程共享。堆內(nèi)存隨著JVM啟動而創(chuàng)建。

參數(shù)設(shè)置:

-Xms:堆的最小值

-Xmx:堆的最大值

-Xmn:新生代的大小

-XX:NewSize;新生代最小值

-XX:MaxNewSize:新生代最大值

八、運行時常量池

8.1、符號引用

  • 一個 java 類(假設(shè)為 People 類)被編譯成一個 class 文件時,如果 People 類引用了 Tool 類,但是在編譯時 People 類并不知道引用類的實際內(nèi)存地址,因此只能使用符號引用來代替。
  • 而在類裝載器裝載 People 類時,此時可以通過虛擬機獲取 Tool 類的實際內(nèi)存地址,因此便可以既將符號 org.simple.Tool 替換為 Tool 類的實際內(nèi)存地址,及直接引用地址。
  • 即在編譯時用符號引用來代替引用類,在加載時再通過虛擬機獲取該引用類的實際地址。
  • 以一組符號來描述所引用的目標,符號可以是任何形式的字面量,只要使用時能無歧義地定位到目標即可。符號引用與虛擬機實現(xiàn)的內(nèi)存布局是無關(guān)的,引用的目標不一定已經(jīng)加載到內(nèi)存中。

8.2、字面量

  • 文本字符串 String a = "abc",這個 abc 就是字面量。
  • 八種基本類型 int a = 1; 這個 1 就是字面量。
  • 聲明為 final 的常量。

8.3、jvm各版本運行時常量池變化

  • 運行時常量池:Class 文件中的常量池(編譯器生成的各種字面量和符號引用)會在類加載后被放入這個區(qū)域。
  • JDK1.6:運行時常量池在方法區(qū)(永久代)中。
  • JDK1.7:運行時常量池在堆中。
  • JDK1.8:去永久代:使用元空間(空間大小只受制于機器的內(nèi)存)替代永久代。

8.4、直接內(nèi)存

內(nèi)存對象分配在JVM中堆以外的內(nèi)存,也可以稱為直接內(nèi)存,這些內(nèi)存直接受操作系統(tǒng)管理(而不是JVM),這樣做的好處是能夠在一定程度上減少垃圾回收對應(yīng)用程序造成的影響。

  • 使用 Native 函數(shù)庫直接分配堆外內(nèi)存(NIO)。
  • 并不是 JVM 運行時數(shù)據(jù)區(qū)域的一部分,但是會被頻繁使用(可以通過-XX:MaxDirectMemorySize 來設(shè)置(默認與堆內(nèi)存最大值一樣,也會出現(xiàn) OOM 異常)。
  • 避免了在 Java 堆和 Native 堆中來回復(fù)制數(shù)據(jù),能夠提高效率。

以上就是分析JVM的組成結(jié)構(gòu)的詳細內(nèi)容,更多關(guān)于JVM組成結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringMVC項目異常處理機制詳解

    SpringMVC項目異常處理機制詳解

    SpringMVC是一種基于Java,實現(xiàn)了Web MVC設(shè)計模式,請求驅(qū)動類型的輕量級Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進行職責解耦?;谡埱篁?qū)動指的就是使用請求-響應(yīng)模型,框架的目的就是幫助我們簡化開發(fā),SpringMVC也是要簡化我們?nèi)粘eb開發(fā)
    2022-08-08
  • 下載遠程maven倉庫的jar?手動放到本地倉庫詳細操作

    下載遠程maven倉庫的jar?手動放到本地倉庫詳細操作

    這篇文章主要介紹了如何下載遠程maven倉庫的jar?手動放到本地倉庫,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • JAVA實現(xiàn)Excel和PDF上下標的操作代碼

    JAVA實現(xiàn)Excel和PDF上下標的操作代碼

    這篇文章主要介紹了JAVA實現(xiàn)Excel和PDF上下標,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • 一文掌握SpringSecurity?BCrypt密碼加密和解密

    一文掌握SpringSecurity?BCrypt密碼加密和解密

    BCrypt就是一款加密工具,可以比較方便地實現(xiàn)數(shù)據(jù)的加密工作。也可以簡單理解為它內(nèi)部自己實現(xiàn)了隨機加鹽處理,這篇文章主要介紹了SpringSecurity?BCrypt密碼加密和解密,一文學(xué)會使用BCryptPasswordEncoder的方法,需要的朋友可以參考下
    2023-04-04
  • Java攔截器Interceptor和過濾器Filte的執(zhí)行順序和區(qū)別

    Java攔截器Interceptor和過濾器Filte的執(zhí)行順序和區(qū)別

    本文主要介紹了Java攔截器Interceptor和過濾器Filte的執(zhí)行順序和區(qū)別,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 關(guān)于Spring中聲明式事務(wù)的使用詳解

    關(guān)于Spring中聲明式事務(wù)的使用詳解

    Spring中事務(wù)分為編程式事務(wù)和聲明式事務(wù),編程式事務(wù)由于需要在代碼中硬編碼,在實際項目開發(fā)中比較少用到,實際開發(fā)中用的比較多的就是聲明式事務(wù),這篇文章主要給大家介紹了關(guān)于Spring中聲明式事務(wù)使用的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • springboot統(tǒng)一異常處理(返回json)并格式化異常

    springboot統(tǒng)一異常處理(返回json)并格式化異常

    這篇文章主要介紹了springboot統(tǒng)一異常處理(返回json)并格式化異常,對spring boot的默認異常處理方式進行修改,要統(tǒng)一返回數(shù)據(jù)格式,優(yōu)雅的數(shù)據(jù)交互,優(yōu)雅的開發(fā)應(yīng)用,需要的朋友可以參考下
    2023-07-07
  • Java中的接口和抽象類用法實例詳解

    Java中的接口和抽象類用法實例詳解

    這篇文章主要介紹了Java中的接口和抽象類用法,結(jié)合實例形式較為詳細的分析了Java中關(guān)于接口和抽象類的概念、定義、用法與相關(guān)注意事項,需要的朋友可以參考下
    2015-12-12
  • 一次排查@CacheEvict注解失效的經(jīng)歷及解決

    一次排查@CacheEvict注解失效的經(jīng)歷及解決

    這篇文章主要介紹了一次排查@CacheEvict注解失效的經(jīng)歷及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java后端學(xué)習精華之TCP通信傳輸協(xié)議詳解

    Java后端學(xué)習精華之TCP通信傳輸協(xié)議詳解

    TCP/IP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,它會保證數(shù)據(jù)不丟包、不亂序。TCP全名是Transmission Control Protocol,它是位于網(wǎng)絡(luò)OSI模型中的第四層
    2021-09-09

最新評論

建水县| 通榆县| 沭阳县| 绵竹市| 花莲县| 林西县| 内丘县| 婺源县| 抚松县| 万盛区| 都安| 大竹县| 巧家县| 望城县| 萨嘎县| 双鸭山市| 金坛市| 伽师县| 开江县| 临泽县| 华宁县| 洪泽县| 贵阳市| 汕头市| 察隅县| 华亭县| 晴隆县| 应城市| 磐石市| 盖州市| 白玉县| 通榆县| 大理市| 沈阳市| 礼泉县| 莲花县| 大庆市| 海晏县| 淄博市| 和田县| 东乡|