国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運營 > 深入了解Java虛擬機(jī)(JVM)

深入了解Java虛擬機(jī)(JVM)

時間:2023-07-01 02:21:01 | 來源:網(wǎng)站運營

時間:2023-07-01 02:21:01 來源:網(wǎng)站運營

深入了解Java虛擬機(jī)(JVM):

什么是JVM?

JVM是JRE的一部分。它是一個虛構(gòu)出來的計算機(jī),是通過在實際的計算機(jī)上仿真模擬各種計算機(jī)功能來實現(xiàn)的。JVM有自己完善的硬件架構(gòu),如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。Java語言最重要的特點就是跨平臺運行。使用JVM就是為了支持與操作系統(tǒng)無關(guān),實現(xiàn)跨平臺。所以,JAVA虛擬機(jī)JVM是屬于JRE的,而現(xiàn)在我們安裝JDK時也附帶安裝了JRE(當(dāng)然也可以單獨安裝JRE)。

JVM在執(zhí)行字節(jié)碼時,實際上最終還是把字節(jié)碼解釋成具體平臺上的機(jī)器指令執(zhí)行。




JDK,JVM,JRE三者之間的聯(lián)系

JVM就是我們常說的java虛擬機(jī),它是整個java實現(xiàn)跨平臺的 最核心的部分,所有的java程序會首先被編譯為.class的類文件,這種類文件可 以在虛擬機(jī)上執(zhí)行,也就是說class并不直接與機(jī)器的操作系統(tǒng)相對應(yīng),而是經(jīng)過虛擬機(jī)間接與操作系統(tǒng)交互,由虛擬機(jī)將程序解 釋給本地系統(tǒng)執(zhí)行。

JRE是指java運行環(huán)境。光有JVM還不能成class的 執(zhí)行,因為在解釋class的時候JVM需要調(diào)用解釋所需要的類庫lib。 在JDK的安裝目 錄里你可以找到j(luò)re目錄,里面有兩個文件夾bin和lib,在 這里可以認(rèn)為bin里的就是jvm,lib中則是jvm工 作所需要的類庫,而jvm和 lib和起來就稱為jre。

JDK是java開發(fā)工具包,開發(fā)者用來編譯和調(diào)試,基本上每個學(xué)java的人都會先在機(jī)器 上裝一個JDK,那他都包含哪幾部分呢?讓我們看一下JDK的安裝目錄。在目錄下面有 六個文件夾、一個src類庫源碼壓縮包、和其他幾個聲明文件。其中,真正在運行java時起作用的 是以下四個文件夾:bin、include、lib、 jre?,F(xiàn)在我們可以看出這樣一個關(guān)系,JDK包含JRE,而JRE包 含JVM。




JVM執(zhí)行程序的過程

1) 加載.class文件

2) 管理并分配內(nèi)存

3) 執(zhí)行垃圾收集

JRE(java運行時環(huán)境)由JVM構(gòu)造的java程序的運行環(huán),也是Java程序運行的環(huán)境,但是他同時一個操作系統(tǒng)的一個應(yīng)用程序一個進(jìn)程,

因此他也有他自己的運行的生命周期,也有自己的代碼和數(shù)據(jù)空間。

JVM在整個jdk中處于最底層,負(fù)責(zé)于操作系統(tǒng)的交互,用來屏蔽操作系統(tǒng)環(huán)境,

提供一個完整的Java運行環(huán)境,因此也就虛擬計算機(jī)。




JVM的生命周期

1) JVM實例對應(yīng)了一個獨立運行的java程序它是進(jìn)程級別

a) 啟動。啟動一個Java程序時,一個JVM實例就產(chǎn)生了,任何一個擁有public static void

main(String[] args)函數(shù)的class都可以作為JVM實例運行的起點

b) 運行。main()作為該程序初始線程的起點,任何其他線程均由該線程啟動。JVM內(nèi)部有兩種線程:守護(hù)線程和非守護(hù)線程,main()屬于非守護(hù)線程,守護(hù)線程通常由JVM自己使用,java程序也可以表明自己創(chuàng)建的線程是守護(hù)線程

c) 消亡。當(dāng)程序中的所有非守護(hù)線程都終止時,JVM才退出;若安全管理器允許,程序也可以使用Runtime類或者System.exit()來退出

2) JVM執(zhí)行引擎實例則對應(yīng)了屬于用戶運行程序的線程它是線程級別的




Java執(zhí)行過程以及JVM內(nèi)存模型

可以看到j(luò)ava的執(zhí)行過程。

至于類加載器,這里我們先不做過多的介紹,在后續(xù)博客中更新。

運行時數(shù)據(jù)區(qū),即JVM的內(nèi)存模型

方法區(qū)和堆是線程共享,程序計數(shù)器、虛擬機(jī)棧、本地方法棧是線程私有的

這一塊比較重要,接下來詳細(xì)介紹一下運行時數(shù)據(jù)區(qū):

程序計數(shù)器(PC寄存器)

    由于在JVM中,多線程是通過線程輪流切換來獲得CPU執(zhí)行時間的,因此,在任一具體時刻,一個CPU的內(nèi)核只會執(zhí)行一條線程中的指令,

  因此,為了能夠使得每個線程都在線程切換后能夠恢復(fù)在切 換 之前的程序執(zhí)行位置,每個線程都需要有自己獨立的程序計數(shù)器,并且不能互相被干擾,

  否則就會影響到程序的正常執(zhí)行次序。因此,可以這么說,程序計數(shù)器是每個線程所私有的。由于程序計數(shù)器中存儲的數(shù)據(jù)所占空間的大小不會隨程序的執(zhí)行而發(fā)生改變,

  因此,對于程序計數(shù)器是不會發(fā)生內(nèi)存溢出現(xiàn)象(OutOfMemory)的。




虛擬機(jī)棧(VM Stack)

線程私有它的生命周期和線程相同。

JVM的棧中存放的數(shù)據(jù)主要有:

1.各種基礎(chǔ)數(shù)據(jù)類型(boolean、byte、char 、short、int、float、long、double );

2.方法的形式參數(shù),方法調(diào)用完后從??臻g回收;

3.引用對象的地址,引用完后,??臻g地址立即被回收,堆空間等待GC。

JVM的棧也屬于線程私有的內(nèi)存,用戶可以設(shè)置大小。對于異常,這塊區(qū)域有兩種情況:如果線程請求的棧深度大于JVM所允許的深度,將拋出StackOverflowError異常;如果JVM的棧可以動態(tài)擴(kuò)展,但是在嘗試擴(kuò)展時無法申請到足夠的內(nèi)存則拋出OutOfMemoryError異常。




本地方法棧

Java本地方法(Native Method)是由其它語言編寫的,編譯成和處理器相關(guān)的機(jī)器代碼,保存在動態(tài)鏈接庫中,即.dll(windows系統(tǒng))文件中,格式是各個平臺專有的。雖說Java方法是與平臺無關(guān)的,但是本地方法不是。程序運行中Java方法調(diào)用本地方法時,JVM裝載包含這個本地方法的動態(tài)庫的,并調(diào)用這個方法。通過本地方法,Java程序可以直接訪問底層操作系統(tǒng)的資源,如果你這樣用,你的程序就變成平臺相關(guān)了,因為本地方法的動態(tài)庫是與平臺相關(guān)的,但是使用本地方法還可能把程序變得和特定的Java平臺實現(xiàn)相關(guān)。

本地方法棧與虛擬機(jī)棧作用類似,Sun HotSpot中直接將本地方法棧和虛擬機(jī)棧合二為一,它和虛擬機(jī)棧一樣都會拋出StackOverflowError和OutOfMemoryError異常。






Java中的堆是用來存儲對象本身的以及數(shù)組(數(shù)組引用是存放在Java棧中的)。堆是被所有線程共享的,在JVM中只有一個堆。

Java 堆是JVM所管理的內(nèi)存中最大的一塊并且是所有線程共享的內(nèi)存區(qū)域,在JVM啟動時創(chuàng)建。堆存放的就是存放對象實例和數(shù)組,幾乎所有的對象實例都在這里分配內(nèi)存。Java堆是垃圾回收器管理的主要區(qū)域,如果在堆中沒有內(nèi)存完成實例分配,并且堆也無法再擴(kuò)展時,將會拋出OutOfMemoryError 異常




方法區(qū)

方法區(qū)是各個內(nèi)存所共享的內(nèi)存空間, 方法區(qū)中主要存放被JVM加載的類信息、常量、靜態(tài)變量、即時編譯后的代碼等數(shù)據(jù)。方法區(qū)的大小用戶可以更改,如果發(fā)生溢出會出現(xiàn)java.lang.OutOfMemoryError:PermGen space信息。

在方法區(qū)中有一個非常重要的部分就是運行時常量池,它是每一個類或接口的常量池的運行時表示形式,在類和接口被加載到JVM后,

 對應(yīng)的運行時常量池就被創(chuàng)建出來。當(dāng)然并非Class文件常量池中的內(nèi)容才能進(jìn)入運行時常量池,在運行期間也可將新的常量放入運行時常量池中,比如String的intern方法。




直接內(nèi)存

直接內(nèi)存并不是虛擬機(jī)運行時數(shù)據(jù)區(qū)的一部分,也不是JVM規(guī)范中定義的內(nèi)存區(qū)域,但是這部分內(nèi)存也被頻繁地使用,而且也可能導(dǎo)致OutOfMemoryError 異常出現(xiàn)。

為了提高IO速度,在JDK 1.4 中新加入了NIO(New Input/Output)類,引入了一種基于通道(Channel)與緩沖區(qū)(Buffer)的I/O 方式,它可以使用Native 函數(shù)庫直接分配堆外內(nèi)存,然后通過一個存儲在Java 堆里面的DirectByteBuffer 對象作為這塊內(nèi)存的引用進(jìn)行操作。這樣能在一些場景中顯著提高性能,因為避免了在Java 堆和Native 堆中來回復(fù)制數(shù)據(jù)。顯然,本機(jī)直接內(nèi)存的分配不會受到Java 堆大小的限制,但是,既然是內(nèi)存,則肯定還是會受到本機(jī)總內(nèi)存(包括RAM 及SWAP 區(qū)或者分頁文件)的大小及處理器尋址空間的限制。服務(wù)器管理員配置虛擬機(jī)參數(shù)時,一般會根據(jù)實際內(nèi)存設(shè)置-Xmx等參數(shù)信息,但經(jīng)常會忽略掉直接內(nèi)存,使得各個內(nèi)存區(qū)域的總和大于物理內(nèi)存限制(包括物理上的和操作系統(tǒng)級的限制),從而導(dǎo)致動態(tài)擴(kuò)展時出現(xiàn)OutOfMemoryError異常。




總結(jié):JVM內(nèi)存溢出的情況





















關(guān)鍵詞:虛擬,深入

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點擊下載Chrome瀏覽器
關(guān)閉