java虛擬機內(nèi)存模型?
網(wǎng)友解答: 1.什么是jvm?(1)jvm是一種用于計算設備的規(guī)范,它是一個虛構出來的機器,是通過在實際的計算機上仿真模擬各種功能實現(xiàn)的。(2)jvm包含一套字節(jié)碼指令集,一組寄存器,一
1.什么是jvm?(1)jvm是一種用于計算設備的規(guī)范,它是一個虛構出來的機器,是通過在實際的計算機上仿真模擬各種功能實現(xiàn)的。(2)jvm包含一套字節(jié)碼指令集,一組寄存器,一個棧,一個垃圾回收堆和一個存儲方法域。(3)JVM屏蔽了與具體操作系統(tǒng)平臺相關的信息,使Java程序只需生成在Java虛擬機上運行的目標代碼(字節(jié)碼),就可以在多種平臺上不加修改地運行。JVM在執(zhí)行字節(jié)碼時,實際上最終還是把字節(jié)碼解釋成具體平臺上的機器指令執(zhí)行。
2.jdk、jre、jvm是什么關系?(1)JRE(Java Runtime Environment),也就是java平臺。所有的java程序都要在JRE環(huán)境下才能運行。(2)JDK(Java Development Kit),是開發(fā)者用來編譯、調(diào)試程序用的開發(fā)包。JDK也是JAVA程序需要在JRE上運行。(3)JVM(Java Virtual Machine),是JRE的一部分。它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現(xiàn)的。JVM有自己完善的硬件架構,如處理器、堆棧、寄存器等,還具有相應的指令系統(tǒng)。Java語言最重要的特點就是跨平臺運行。使用JVM就是為了支持與操作系統(tǒng)無關,實現(xiàn)跨平臺。
3.JVM原理(1)jvm是java的核心和基礎,在java編譯器和os平臺之間的虛擬處理器,可在上面執(zhí)行字節(jié)碼程序。(2)java編譯器只要面向jvm,生成jvm能理解的字節(jié)碼文件。java源文件經(jīng)編譯成字節(jié)碼程序,通過jvm將每條指令翻譯成不同的機器碼,通過特定平臺運行。
4. JVM執(zhí)行程序的過程1) 加載.class文件 2) 管理并分配內(nèi)存 3) 執(zhí)行垃圾收集JRE(java運行時環(huán)境)由JVM構造的java程序的運行環(huán),也是Java程序運行的環(huán)境,但是他同時一個操作系統(tǒng)的一個應用程序一個進程,因此他也有他自己的運行的生命周期,也有自己的代碼和數(shù)據(jù)空間。JVM在整個jdk中處于最底層,負責于操作系統(tǒng)的交互,用來屏蔽操作系統(tǒng)環(huán)境,提供一個完整的Java運行環(huán)境,因此也就虛擬計算機。操作系統(tǒng)裝入JVM是通過jdk中Java.exe來完成,通過下面4步來完成JVM環(huán)境:1) 創(chuàng)建JVM裝載環(huán)境和配置 2) 裝載JVM.dll 3) 初始化JVM.dll并掛界到JNIENV(JNI調(diào)用接口)實例4) 調(diào)用JNIEnv實例裝載并處理class類。5. JVM的生命周期1) JVM實例對應了一個獨立運行的java程序它是進程級別 a) 啟動。啟動一個Java程序時,一個JVM實例就產(chǎn)生了,任何一個擁有public static void main(String[] args)函數(shù)的class都可以作為JVM實例運行的起點 b) 運行。main()作為該程序初始線程的起點,任何其他線程均由該線程啟動。JVM內(nèi)部有兩種線程:守護線程和非守護線程,main()屬于非守護線程,守護線程通常由JVM自己使用,java程序也可以表明自己創(chuàng)建的線程是守護線程 c) 消亡。當程序中的所有非守護線程都終止時,JVM才退出;若安全管理器允許,程序也可以使用Runtime類或者System.exit()來退出 2) JVM執(zhí)行引擎實例則對應了屬于用戶運行程序的線程它是線程級別的
6、JVM內(nèi)存模型
(1)java代碼具體執(zhí)行過程如下圖,
(2)運行時數(shù)據(jù)區(qū),即jvm內(nèi)存結構圖如下圖
(3)運行時數(shù)據(jù)區(qū)存儲了哪些數(shù)據(jù)?
a) 程序計數(shù)器(PC寄存器)
由于在JVM中,多線程是通過線程輪流切換來獲得CPU執(zhí)行時間的,因此,在任一具體時刻,一個CPU的內(nèi)核只會執(zhí)行一條線程中的指令,
因此,為了能夠使得每個線程都在線程切換后能夠恢復在切 換 之前的程序執(zhí)行位置,每個線程都需要有自己獨立的程序計數(shù)器,并且不能互相被干擾,
否則就會影響到程序的正常執(zhí)行次序。因此,可以這么說,程序計數(shù)器是每個線程所私有的。由于程序計數(shù)器中存儲的數(shù)據(jù)所占空間的大小不會隨程序的執(zhí)行而發(fā)生改變,
因此,對于程序計數(shù)器是不會發(fā)生內(nèi)存溢出現(xiàn)象(OutOfMemory)的。
b) java棧
Java棧中存放的是一個個的棧幀,每個棧幀對應一個被調(diào)用的方法,在棧幀中包括局部變量表(Local Variables)、操作數(shù)棧(Operand Stack)、
指向當前方法所屬的類的運行時常量池(運行時常量池的概念在方法區(qū)部分會談到)的引用(Reference to runtime constant pool)、
方法返回地址(Return Address)和一些額外的附加信息。當線程執(zhí)行一個方法時,就會隨之創(chuàng)建一個對應的棧幀,并將建立的棧幀壓棧。當方法執(zhí)行完畢之后,便會將棧幀出棧?!?/p>
c)本地方法棧
本地方法棧與Java棧的作用和原理非常相似。區(qū)別只不過是Java棧是為執(zhí)行Java方法服務的,而本地方法棧則是為執(zhí)行本地方法(Native Method)服務的
d)堆
Java中的堆是用來存儲對象本身的以及數(shù)組(數(shù)組引用是存放在Java棧中的)。堆是被所有線程共享的,在JVM中只有一個堆。
e)方法區(qū)
與堆一樣,是被線程共享的區(qū)域。在方法區(qū)中,存儲了每個類的信息(包括類的名稱、方法信息、字段信息)、靜態(tài)變量、常量以及編譯器編譯后的代碼等。
在Class文件中除了類的字段、方法、接口等描述信息外,還有一項信息是常量池,用來存儲編譯期間生成的字面量和符號引用。
在方法區(qū)中有一個非常重要的部分就是運行時常量池,它是每一個類或接口的常量池的運行時表示形式,在類和接口被加載到JVM后,
對應的運行時常量池就被創(chuàng)建出來。當然并非Class文件常量池中的內(nèi)容才能進入運行時常量池,在運行期間也可將新的常量放入運行時常量池中,比如String的intern方法。
7、JVM內(nèi)存溢出的情況
a) 程序計數(shù)器(Program Counter Register)
每條線程都有一個獨立的的程序計數(shù)器,各線程間的計數(shù)器互不影響,因此該區(qū)域是線程私有的。該內(nèi)存區(qū)域是唯一一個在Java虛擬機規(guī)范中沒有規(guī)定任何OOM(內(nèi)存溢出:OutOfMemoryError)情況的區(qū)域。
b)Java虛擬機棧(Java Virtual Machine Stacks)
在Java虛擬機規(guī)范中,對這個區(qū)域規(guī)定了兩種異常情況:
1、如果線程請求的棧深度大于虛擬機所允許的深度,將拋出StackOverflowError異常。
2、如果虛擬機在動態(tài)擴展棧時無法申請到足夠的內(nèi)存空間,則拋出OutOfMemoryError異常。
這兩種情況存在著一些互相重疊的地方:當??臻g無法繼續(xù)分配時,到底是內(nèi)存太小,還是已使用的??臻g太大,其本質(zhì)上只是對同一件事情的兩種描述而已。
在單線程的操作中,無論是由于棧幀太大,還是虛擬機??臻g太小,當??臻g無法分配時,虛擬機拋出的都是StackOverflowError異常,而不會得到OutOfMemoryError異常。
而在多線程環(huán)境下,則會拋出OutOfMemoryError異常。
c)堆Java Heap
Java Heap是Java虛擬機所管理的內(nèi)存中最大的一塊,它是所有線程共享的一塊內(nèi)存區(qū)域。幾乎所有的對象實例和數(shù)組都在這類分配內(nèi)存。Java Heap是垃圾收集器管理的主要區(qū)域,因此很多時候也被稱為“GC堆”。
根據(jù)Java虛擬機規(guī)范的規(guī)定,Java堆可以處在物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的即可。如果在堆中沒有內(nèi)存可分配時,并且堆也無法擴展時,將會拋出OutOfMemoryError異常。
d)方法區(qū)域,又被稱為“永久代”,當方法區(qū)無法滿足內(nèi)存分配需求時,將拋出OutOfMemoryError異常。
網(wǎng)友解答:
走向架構師,你必須了解的Java虛擬機高級特性
鏈接: https://pan.baidu.com/s/1hAPo19keNFHb9ycBctkU2A 密碼: iayw
看完了你就知道Java虛擬機了 不要謝我 、
對了
記得點贊關注一下我酷米號Java分布式