欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java程序執(zhí)行過(guò)程及內(nèi)存機(jī)制詳解

 更新時(shí)間:2020年12月12日 09:06:06   作者:說(shuō)人話  
本講將介紹Java代碼是如何一步步運(yùn)行起來(lái)的,還會(huì)介紹Java程序所占用的內(nèi)存是被如何管理的:堆、棧和方法區(qū)都各自負(fù)責(zé)存儲(chǔ)哪些內(nèi)容,感興趣的朋友跟隨小編一起看看吧

本講將介紹Java代碼是如何一步步運(yùn)行起來(lái)的,其中涉及的編譯器,類加載器,字節(jié)碼校驗(yàn)器,解釋器和JIT編譯器在整個(gè)過(guò)程中是發(fā)揮著怎樣的作用。此外還會(huì)介紹Java程序所占用的內(nèi)存是被如何管理的:堆、棧和方法區(qū)都各自負(fù)責(zé)存儲(chǔ)哪些內(nèi)容。最后用一小塊代碼示例來(lái)幫助理解Java程序運(yùn)行時(shí)內(nèi)存的變化。

Java程序執(zhí)行過(guò)程

  • 步驟 1: 寫源代碼,源代碼將以.java的文件格式保存在電腦硬盤中。
  • 步驟 2: 編譯器(compiler)檢查是否存在編譯期錯(cuò)誤(例如缺少分號(hào),關(guān)鍵字拼寫錯(cuò)誤等)。若通過(guò)檢測(cè),編譯器就會(huì)將源代碼翻譯成字節(jié)碼(bytecode),以.class的文件格式保存在電腦硬盤中。
  • 步驟 3: 若要運(yùn)行此Java程序,JVM中會(huì)有一個(gè)叫類加載器(class loader)的內(nèi)置程序把字節(jié)碼從硬盤載入到正位于內(nèi)存中的JVM里去。
  • 步驟 4: JVM中還有一個(gè)叫字節(jié)碼校驗(yàn)器(bytecode verifier)的內(nèi)置程序檢測(cè)是否存在運(yùn)行期錯(cuò)誤(例如棧溢出)。若通過(guò)檢測(cè),字節(jié)碼校驗(yàn)器就會(huì)將字節(jié)碼傳遞給解釋器(interpreter)。
  • 步驟 5: 解釋器會(huì)對(duì)字節(jié)碼進(jìn)行逐行翻譯,將其翻譯成當(dāng)前所在系統(tǒng)可以理解的機(jī)器碼(machine code),
  • 步驟 6:將機(jī)器碼交給操作系統(tǒng),操作系統(tǒng)會(huì)以main方法作為入口開(kāi)始執(zhí)行程序。至此,一個(gè)Java程序就這樣運(yùn)行起來(lái)了。

細(xì)心的讀者可能注意到了,在流程圖中還涉及到一個(gè)叫JIT的東西在步驟中沒(méi)有被解釋。那么JIT編譯器(Just-In-Time Compiler)是如果參與進(jìn)程序的執(zhí)行過(guò)程中呢?讓我們來(lái)看以下兩個(gè)例子。

  • 情況 1: 解釋器對(duì)代碼進(jìn)行逐行解釋,正如我們?cè)诓襟E中所介紹的。
  • 情況 2: 這是JIT編譯器參與進(jìn)Java執(zhí)行過(guò)程的情況,JIT編譯器會(huì)掃描所有代碼并對(duì)其進(jìn)行優(yōu)化。例如此時(shí)它發(fā)現(xiàn)最后一行代碼是重復(fù)多余的,就會(huì)將其移除,只傳遞前4行代碼給解釋器。這樣解釋器就能運(yùn)行地更快速高效,畢竟少了一行多余的代碼需要翻譯。

當(dāng)然,這只是JIT編譯器的優(yōu)化手段之一,不同公司設(shè)計(jì)的JIT編譯器對(duì)Java程序的運(yùn)行會(huì)有不同的優(yōu)化方式。此外需要知道的是,JIT編譯器并不是每次都會(huì)參與到執(zhí)行過(guò)程中來(lái)。

內(nèi)存機(jī)制

在步驟3中我們談到字節(jié)碼會(huì)被類加載器載入到內(nèi)存,那么載入之后JVM是如何對(duì)其進(jìn)行內(nèi)存管理的呢?

通常,在載入內(nèi)存后,一個(gè)Java程序所占用的內(nèi)存會(huì)被大致分為3塊區(qū)域:堆(heap),棧(stack)和方法區(qū)(method area)。

堆:存放new出來(lái)的東西。

棧:存放局部變量。

方法區(qū):類型信息,字段信息,常量池(constant pool),靜態(tài)變量,方法信息等。

public final class Student extends Object implements Serializable
{ 
// 1.類信息 
// 2.對(duì)象字段信息 
private String name; 
private int score; 
// 3.常量池 
public final int id = 0; 
public final String gender = "male"; 
// 4.靜態(tài)變量 
public static int a = 0; 
// 5.方法信息 
public int getid() 
{ 
return id; 
}}

PC寄存器:存放將要執(zhí)行的指令的地址。(因?yàn)闄C(jī)器的腦子不靈活,所以需要一塊專門的區(qū)域幫他記住執(zhí)行到哪一步,不然它會(huì)忘記)

本地方法棧:與JVM棧所發(fā)揮的作用是非常相似的,其區(qū)別不過(guò)是JVM棧為Java方法服務(wù),而本地方法棧則是為使用到的Native方法服務(wù)。有的虛擬機(jī)(例如Sun HotSpot虛擬機(jī))甚至直接就把本地方法棧和虛擬機(jī)棧合二為一。

每個(gè)線程擁有各自獨(dú)立的(虛擬機(jī))棧、PC寄存器和本地方法棧。而堆和方法區(qū)則是所有線程共享的。

最后讓我們通過(guò)一個(gè)小例子來(lái)理解Java程序執(zhí)行時(shí)內(nèi)存的變化。

public class Person 
{
int id; int age; Person(int id1, int age1)
{ 
id = id1; age = age1; 
} 
public static void main(String[] args) 
{ 
Person Tom = new Person(1, 25); 
} 
}

首先,在stack中申請(qǐng)了一塊內(nèi)存,這塊內(nèi)存區(qū)域名字叫Tom,此時(shí)區(qū)域里存儲(chǔ)的內(nèi)容為null。

接著,調(diào)用Person的構(gòu)造方法,方法的參數(shù)屬于局部變量,因此在stack中有兩塊區(qū)域分別存放id1和age1。

通過(guò)構(gòu)造方法,可以new出來(lái)一個(gè)Person的對(duì)象,這個(gè)對(duì)象連帶著其成員變量會(huì)被存放在heap中。成員變量id和age的值由存放在stack中的局部變量id1和age1賦予。

最后,將這個(gè)對(duì)象的引用值(類似于地址)傳遞給Tom,通過(guò)引用值我們就可以找到這個(gè)對(duì)象。

(注意:位于stack中的id1和age1會(huì)隨著構(gòu)造方法調(diào)用的結(jié)束而消失,這里為了更好地表現(xiàn)全過(guò)程,因此保留在圖中。)

關(guān)于棧和堆的其他小知識(shí)

  • 棧和堆的大小都是固定為一個(gè)默認(rèn)值的,它們作為jvm的參數(shù)設(shè)定好了,不同的jvm設(shè)定的參數(shù)不同,相應(yīng)的棧和堆的大小也就不同。
  • 棧是運(yùn)行時(shí)的單位:里面存儲(chǔ)的信息都是跟當(dāng)前線程相關(guān)的,包括局部變量、程序運(yùn)行狀態(tài)、方法返回值等;而堆是存儲(chǔ)的單位:它只負(fù)責(zé)存儲(chǔ)對(duì)象。
  • 當(dāng)一個(gè)方法調(diào)用結(jié)束后,方法里的局部變量會(huì)隨之消失,不會(huì)在stack中繼續(xù)占用空間。棧與堆的分離使得不同線程可以訪問(wèn)同一個(gè)對(duì)象,這是一種有效的數(shù)據(jù)交互方式(共享內(nèi)存);此外也節(jié)省了空間,因?yàn)槎阎械墓蚕沓A亢途彺婵梢员凰袟TL問(wèn)。

參考https://simplesnippets.tech/execution-process-of-java-program-in-detail-working-of-just-it-time-compiler-jit-in-detail/https://blog.csdn.net/yfqnihao/article/details/8289363https://www.zhihu.com/question/29833675

到此這篇關(guān)于Java程序執(zhí)行過(guò)程及內(nèi)存機(jī)制詳解的文章就介紹到這了,更多相關(guān)Java程序執(zhí)行過(guò)程及內(nèi)存機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

到此這篇關(guān)于Java程序執(zhí)行過(guò)程及內(nèi)存機(jī)制詳解的文章就介紹到這了,更多相關(guān)Java程序執(zhí)行過(guò)程及內(nèi)存機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java設(shè)計(jì)模式之責(zé)任鏈模式詳解

    Java設(shè)計(jì)模式之責(zé)任鏈模式詳解

    客戶端發(fā)出一個(gè)請(qǐng)求,鏈上的對(duì)象都有機(jī)會(huì)來(lái)處理這一請(qǐng)求,而客戶端不需要知道誰(shuí)是具體的處理對(duì)象。這樣就實(shí)現(xiàn)了請(qǐng)求者和接受者之間的解耦,并且在客戶端可以實(shí)現(xiàn)動(dòng)態(tài)的組合職責(zé)鏈。使編程更有靈活性
    2022-07-07
  • Spring中IOC和AOP的核心組成架構(gòu)詳解

    Spring中IOC和AOP的核心組成架構(gòu)詳解

    這篇文章主要介紹了Spring中IOC和AOP的核心組成架構(gòu)詳解,本文是對(duì)Spring的2大核心功能——IoC和AOP 的總結(jié)提煉,并增加了環(huán)境profile和條件化bean的內(nèi)容,篇幅較短,更像是一個(gè)大綱,或者思維導(dǎo)圖,需要的朋友可以參考下
    2023-08-08
  • IDEA中程序包Org.Springframework.Boot不存在問(wèn)題及解決

    IDEA中程序包Org.Springframework.Boot不存在問(wèn)題及解決

    這篇文章主要介紹了IDEA中程序包Org.Springframework.Boot不存在問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 新手初學(xué)Java List 接口

    新手初學(xué)Java List 接口

    這篇文章主要介紹了Java集合操作之List接口及其實(shí)現(xiàn)方法,詳細(xì)分析了Java集合操作中List接口原理、功能、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2021-07-07
  • Java Netty HTTP服務(wù)實(shí)現(xiàn)過(guò)程解析

    Java Netty HTTP服務(wù)實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Java Netty HTTP服務(wù)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 解析Mybatis Porxy動(dòng)態(tài)代理和sql解析替換問(wèn)題

    解析Mybatis Porxy動(dòng)態(tài)代理和sql解析替換問(wèn)題

    這篇文章主要介紹了Mybatis Porxy動(dòng)態(tài)代理和sql解析替換,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Java詳解對(duì)象終止方法finalize()的用法

    Java詳解對(duì)象終止方法finalize()的用法

    在前面的 jvm 中, 需要補(bǔ)充幾個(gè)部分的內(nèi)容, 接著來(lái)看 finalize() 機(jī)制, 它可以使接近死亡的對(duì)象復(fù)活, 下來(lái)我們來(lái)看是怎么一回事
    2022-05-05
  • SpringBoot校園綜合管理系統(tǒng)實(shí)現(xiàn)流程分步講解

    SpringBoot校園綜合管理系統(tǒng)實(shí)現(xiàn)流程分步講解

    這篇文章主要介紹了SpringBoot+Vue實(shí)現(xiàn)校園綜合管理系統(tǒng)流程分步講解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-09-09
  • Java NIO三大組件與ByteBuffer深入理解及使用

    Java NIO三大組件與ByteBuffer深入理解及使用

    這篇文章主要介紹了Java NIO三大組件與ByteBuffer,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • Java實(shí)現(xiàn)抽獎(jiǎng)功能

    Java實(shí)現(xiàn)抽獎(jiǎng)功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)抽獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11

最新評(píng)論