jvm虚拟机内存结构_JVM体系结构101:了解您的虚拟机
jvm虛擬機(jī)內(nèi)存結(jié)構(gòu)
Java虛擬機(jī)(JVM)架構(gòu)和Java字節(jié)碼101的初學(xué)者速成班
Java應(yīng)用程序無處不在,它們?cè)谖覀兊氖謾C(jī),平板電腦和計(jì)算機(jī)上。 在許多編程語言中,這意味著多次編譯代碼以使其在不同的OS上運(yùn)行。 對(duì)于我們作為開發(fā)人員來說,關(guān)于Java的最酷的事情可能是Java的設(shè)計(jì)與平臺(tái)無關(guān)(俗話說“寫一次,在任何地方運(yùn)行”),因此我們只需要編寫和編譯一次代碼。
這怎么可能? 讓我們深入研究Java虛擬機(jī)(JVM)進(jìn)行查找。
JVM架構(gòu)
這聽起來可能令人驚訝,但是JVM本身對(duì)Java編程語言一無所知。 相反,它知道如何執(zhí)行自己的稱為Java字節(jié)碼的指令集,該指令集以二進(jìn)制類文件進(jìn)行組織。 Java代碼由javac命令編譯為Java字節(jié)碼,然后由JVM在運(yùn)行時(shí)將其翻譯成機(jī)器指令。
線程數(shù)
Java被設(shè)計(jì)為并發(fā)的,這意味著可以通過在同一進(jìn)程中運(yùn)行多個(gè)線程來同時(shí)執(zhí)行不同的計(jì)算。 當(dāng)新的JVM進(jìn)程啟動(dòng)時(shí),將在JVM中創(chuàng)建一個(gè)新線程(稱為main thread )。 從該主線程開始,代碼開始運(yùn)行,并且可以生成其他線程。 實(shí)際的應(yīng)用程序可以具有成千上萬個(gè)運(yùn)行線程,這些線程可以滿足不同的目的。 有些服務(wù)于用戶請(qǐng)求,另一些則執(zhí)行異步后端任務(wù),等等。
堆棧和框架
每個(gè)Java線程都會(huì)與框架堆棧一起創(chuàng)建,該框架堆棧用于保存方法框架并控制方法的調(diào)用和返回。 方法框架用于存儲(chǔ)數(shù)據(jù)及其所屬方法的部分計(jì)算。 方法返回時(shí),其框架將被丟棄。 然后,將其返回值傳遞回調(diào)用程序框架,現(xiàn)在可以使用它來完成自己的計(jì)算。
JVM流程結(jié)構(gòu)
用于執(zhí)行方法的JVM游樂場(chǎng)是方法框架。 框架包括兩個(gè)主要部分:
框架結(jié)構(gòu)
幾乎每個(gè)字節(jié)碼命令都會(huì)操縱這兩個(gè)命令中的至少一個(gè)。 讓我們看看如何。
這個(gè)怎么運(yùn)作
讓我們來看一個(gè)簡單的示例,以了解不同元素如何一起運(yùn)行以運(yùn)行我們的程序。 假設(shè)我們有一個(gè)簡單的程序來計(jì)算2 + 3的值并打印結(jié)果:
class SimpleExample {public static void main(String[] args) {int result = add(2,3);System.out.println(result);}public static int add(int a, int b) {return a+b;} }要編譯此類,我們運(yùn)行javac SimpleExample.java ,生成編譯文件SimpleExample.class 。 我們已經(jīng)知道這是一個(gè)包含字節(jié)碼的二進(jìn)制文件。 那么我們?nèi)绾螜z查類字節(jié)碼呢? 使用javap 。
javap是JDK附帶的命令行工具,可以反匯編類文件。 調(diào)用javap -c -p會(huì)打印出該類的反匯編字節(jié)碼(-c),包括私有(-p)成員和方法:
Compiled from "SimpleExample.java" class SimpleExample {SimpleExample();Code:0: aload_01: invokespecial #1 // Method java/lang/Object."":()V4: returnpublic static void main(java.lang.String[]);Code:0: iconst_21: iconst_32: invokestatic #2 // Method add:(II)I5: istore_16: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;9: iload_110: invokevirtual #4 // Method java/io/PrintStream.println:(I)V13: returnpublic static int add(int, int);Code:0: iload_01: iload_12: iadd3: ireturn }現(xiàn)在,JVM在運(yùn)行時(shí)會(huì)發(fā)生什么? java SimpleExample啟動(dòng)一個(gè)新的JVM進(jìn)程,并創(chuàng)建了主線程。 為main方法創(chuàng)建一個(gè)新框架,并將其推入線程堆棧。
public static void main(java.lang.String[]);Code:0: iconst_21: iconst_32: invokestatic #2 // Method add:(II)I5: istore_16: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;9: iload_110: invokevirtual #4 // Method java/io/PrintStream.println:(I)V13: return
主要方法有兩個(gè)變量: args和result 。 兩者都駐留在局部變量表中。 main的前兩個(gè)字節(jié)碼命令iconst_2和iconst_3將常量值2和3分別加載到操作數(shù)堆棧中。 下一個(gè)命令invokestatic調(diào)用靜態(tài)方法add。 由于此方法需要兩個(gè)整數(shù)作為參數(shù),因此invokestatic從操作數(shù)堆棧中彈出兩個(gè)元素,并將它們傳遞給JVM為add添加的新幀。 此時(shí)主操作數(shù)堆棧為空。
public static int add(int, int);Code:0: iload_01: iload_12: iadd3: ireturn
在添加框架中,這些參數(shù)存儲(chǔ)在局部變量數(shù)組中。 前兩個(gè)字節(jié)碼命令iload_0和iload_1將第0個(gè)和第1個(gè)局部變量加載到堆棧中。 接下來, iadd從操作數(shù)堆棧中彈出前兩個(gè)元素,對(duì)其求和,然后將結(jié)果推回堆棧中。 最后, ireturn彈出頂部元素,并將其作為方法的返回值傳遞給調(diào)用框架,并丟棄該框架。
public static void main(java.lang.String[]);Code:0: iconst_21: iconst_32: invokestatic #2 // Method add:(II)I5: istore_16: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;9: iload_110: invokevirtual #4 // Method java/io/PrintStream.println:(I)V13: return main的堆棧現(xiàn)在保存add的返回值。 istore_1將其彈出并將其設(shè)置為索引1處的變量的值,即result 。 getstatic將類型為java / io / PrintStream的靜態(tài)字段java / lang / System.out壓入堆棧。 iload_1將索引1處的變量(現(xiàn)在等于5的結(jié)果值)壓入堆棧。 因此,此時(shí)堆棧擁有2個(gè)值:“ out”字段和值5。現(xiàn)在invokevirtual將要調(diào)用PrintStream.println方法。 它從堆棧中彈出兩個(gè)元素:第一個(gè)元素是對(duì)將要調(diào)用println方法的對(duì)象的引用。 第二個(gè)元素是要傳遞給println方法的整數(shù)參數(shù),該參數(shù)需要一個(gè)參數(shù)。 這是main方法打印add結(jié)果的地方。 最后, 返回命令完成該方法。 主機(jī)被丟棄,JVM進(jìn)程結(jié)束。
就是這個(gè)。 總而言之,不太復(fù)雜。
“一次編寫,隨處運(yùn)行”
那么,什么使Java平臺(tái)獨(dú)立呢? 全部都在字節(jié)碼中。
如我們所見,任何Java程序都可以編譯為標(biāo)準(zhǔn)Java字節(jié)碼。 然后,JVM在運(yùn)行時(shí)將其轉(zhuǎn)換為特定的機(jī)器指令。 我們不再需要確保我們的代碼與機(jī)器兼容。 相反,我們的應(yīng)用程序可以在裝有JVM的任何設(shè)備上運(yùn)行,并且JVM將為我們完成此操作。 JVM維護(hù)人員的工作是提供不同版本的JVM,以支持不同的機(jī)器和操作系統(tǒng)。
這種體系結(jié)構(gòu)使任何Java程序都可以在安裝了JVM的任何設(shè)備上運(yùn)行。 這樣魔術(shù)就發(fā)生了。
最后的想法
Java開發(fā)人員可以在不了解JVM如何工作的情況下編寫出色的應(yīng)用程序。 但是,深入研究JVM體系結(jié)構(gòu),學(xué)習(xí)其結(jié)構(gòu)并了解其如何解釋代碼將有助于您成為更好的開發(fā)人員。 它還將幫助您不時(shí)解決非常復(fù)雜的問題
PS。 如果您想更深入地了解JVM以及所有這些與Java異常的關(guān)系,那就別無所求! ( 這里可以。 )
翻譯自: https://www.javacodegeeks.com/2018/05/jvm-architecture-101-get-to-know-your-virtual-machine.html
jvm虛擬機(jī)內(nèi)存結(jié)構(gòu)
總結(jié)
以上是生活随笔為你收集整理的jvm虚拟机内存结构_JVM体系结构101:了解您的虚拟机的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jakarta ee_Jakarta E
- 下一篇: 震惊kafka_5个令人震惊的统计数据证