91在线一级黄片|91视频在线观看18|成人夜间呦呦网站|91资源欧美日韩超碰|久久最新免费精品视频一区二区三区|国产探花视频在线观看|黄片真人免费三级片毛片|国产人无码视频在线|精品成人影视无码三区|久久视频爱久久免费精品

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
面試必問,JVM內(nèi)存模型掃盲

JVM簡介

JVM(Java Virtual Machine,Java虛擬機)是Java語言的核心,是一個用于解釋Java字節(jié)碼的虛擬計算機。它可以在運行Java程序時自動管理內(nèi)存、處理異常等。Java程序員不需要關(guān)心底層硬件和操作系統(tǒng)的細節(jié),只需要編寫符合Java語法規(guī)范的代碼,就可以實現(xiàn)跨平臺的編程。

橋東網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)自2013年創(chuàng)立以來到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)。

當我們編寫Java程序時,Java源代碼會被編譯成為Java字節(jié)碼( .java 文件被編譯成 .class 文件)。這些字節(jié)碼可以在任何安裝了Java虛擬機的平臺上運行。JVM在執(zhí)行Java字節(jié)碼時,將其轉(zhuǎn)換成特定于底層CPU和操作系統(tǒng)的機器代碼。

運行時數(shù)據(jù)區(qū)簡介

為了執(zhí)行字節(jié)碼,JVM在內(nèi)存中定義了一系列的數(shù)據(jù)區(qū),用于在運行時存儲各類數(shù)據(jù),即運行時數(shù)據(jù)區(qū)(Runtime Data Areas)。理解這些數(shù)據(jù)區(qū)及其作用,是掌握Java性能調(diào)優(yōu)和錯誤排查的關(guān)鍵。

JVM 運行時數(shù)據(jù)區(qū)是 Java 虛擬機在執(zhí)行 Java 程序時用于數(shù)據(jù)存儲的內(nèi)存區(qū)域,這些區(qū)域各司其職,確保了 Java 程序的正確執(zhí)行。JVM 運行時數(shù)據(jù)區(qū)主要分為五個部分:程序計數(shù)器(Program Counter Register)、虛擬機棧(VM Stack)、本地方法棧(Native Method Stack)、堆(Heap)、方法區(qū)(Method Area)。JVM運行時數(shù)據(jù)區(qū)在程序運行時動態(tài)地分配和釋放內(nèi)存,內(nèi)存管理由JVM自動完成。不同的數(shù)據(jù)區(qū)域有不同的內(nèi)存管理機制和垃圾回收算法,以保證程序運行的效率和穩(wěn)定性。

其中程序計數(shù)器、虛擬機棧、本地方法棧屬于線程私有區(qū)域,跟隨線程的啟動和結(jié)束而建立和銷毀。堆和方法區(qū)是線程共享區(qū)域,跟隨虛擬機進程的啟動而存在。

程序計數(shù)器(Program Counter Register) 是一塊較小的內(nèi)存空間,作用是指示當前線程正在執(zhí)行的 JVM 字節(jié)碼指令地址。

虛擬機棧(VM Stack) 存放的是一些基本類型的變量(如int, long)和對象引用。Java 方法執(zhí)行的內(nèi)存模型是以棧幀(Stack Frame)為基礎(chǔ)的,每個方法在執(zhí)行的時候都會創(chuàng)建一個棧幀,棧幀中存放了局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息。

本地方法棧(Native Method Stack) 與虛擬機棧類似,其主要服務(wù)于 JVM 使用到的 Native 方法。

堆區(qū)(Heap) 是 JVM 所管理的最大一塊內(nèi)存空間,主要用于存放所有線程共享的 Java 對象實例。這也是垃圾回收器主要活動區(qū)域。

方法區(qū)(Method Area) 是用來存儲加載的類信息、常量、靜態(tài)變量等數(shù)據(jù)的。這個區(qū)域是線程共享的。

1. 程序計數(shù)器

程序計數(shù)器(Program Counter Register)是線程私有區(qū)域,生命周期與線程一致,也是 JVM 內(nèi)存中唯一一個沒有任何 OutOfMemoryError 的區(qū)域。

程序計數(shù)器的作用是記錄當前線程正在執(zhí)行的指令地址,換句話說,它指向了下一條將要被執(zhí)行的 JVM 字節(jié)碼指令。在 JVM 的概念模型中,字節(jié)碼解釋器工作時就是通過改變這個計數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令。

當線程執(zhí)行的是 Java 方法時,這個計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令的地址;如果正在執(zhí)行的是 Native 方法,這個計數(shù)器的值則為空(Undefined)。

程序計數(shù)器對于現(xiàn)代多線程而言至關(guān)重要,因為在 CPU 切換各個線程時,需要將各個線程的程序計數(shù)器記錄下來,以便在下一次切換回這個線程時,能知道該從哪里繼續(xù)執(zhí)行。

總結(jié):

  • 程序計數(shù)器是一塊很小的內(nèi)存空間,也是運行速度最快的存儲區(qū)域。
  • 在 JVM 規(guī)范中,每個線程都有它自己的程序計數(shù)器,是線程私有的,生命周期與線程的生命周期一致。
  • 如果當前線程正在執(zhí)行的是 Java 方法,程序計數(shù)器記錄的是 JVM 字節(jié)碼指令地址,如果是執(zhí)行 native 方法,則是未指定值(undefined)
  • 它是程序控制流的指示器,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個計數(shù)器來完成
  • 字節(jié)碼解釋器工作時就是通過改變這個計數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令
  • 它是唯一一個在 JVM 規(guī)范中沒有規(guī)定任何 OutOfMemoryError 情況的區(qū)域

2. 虛擬機棧

與程序計數(shù)器一樣,Java虛擬機棧(Java Virtual Machine Stacks)也是線程私有的,生命周期與線程相同。描述的是Java方法執(zhí)行的內(nèi)存模型。

在 JVM 中,每當一個新的線程被創(chuàng)建,都會創(chuàng)建一個與之關(guān)聯(lián)的私有 JVM 棧。這個棧會隨著線程的運行而進行入棧(push)和出棧(pop)操作。它主要用于存儲局部變量、操作數(shù)堆棧以及方法調(diào)用的情況。

JVM 棧是由一系列棧幀(Stack Frame)組成的。每當一個方法被調(diào)用,一個新的棧幀就會被壓入棧中,每當一個方法調(diào)用結(jié)束,一個棧幀就會被彈出棧。每個棧幀中都包含了局部變量表、操作數(shù)棧、動態(tài)鏈接和方法返回地址等信息。

局部變量表主要存放了編譯期可知的各種基本數(shù)據(jù)類型(boolean、byte、char、short、int、float、long、double)、對象引用(reference 類型,它不等同于指針,可能是一個指向?qū)ο笃鹗嫉刂返囊弥羔?,也可能是指向一個代表對象的句柄或者其他與此對象相關(guān)的位置)和 returnAddress 類型(指向了一條字節(jié)碼指令的地址)。

操作數(shù)棧則是在執(zhí)行字節(jié)碼指令時用到的臨時存儲區(qū),比如在進行算數(shù)運算時,操作數(shù)棧就會用來存放操作數(shù)和接收結(jié)果。

Java虛擬機??赡軙伋鲆韵庐惓#?/p>

  1. 如果線程請求的棧深度大于 JVM 所允許的深度,將拋出 StackOverflowError。
  2. 如果 JVM ??梢詣討B(tài)擴展,當擴展時無法申請到足夠的內(nèi)存,會拋出 OutOfMemoryError。

3. 本地方法棧

本地方法棧(Native Method Stack)也是線程私有,生命周期與線程相同。作用是與虛擬機棧類似,虛擬機棧是為Java 方法服務(wù)的,而本地方法棧是為 Native 方法服務(wù)的。

和虛擬機棧一樣,本地方法棧的大小可以是固定的也可以是動態(tài)的。如果是固定的,當線程請求的棧深度超過最大深度時,會拋出 StackOverflowError。如果是動態(tài)的,并且在嘗試擴展時無法申請到足夠的內(nèi)存,會拋出 OutOfMemoryError。

4. 堆

堆(Heap)是 JVM 所管理的最大一塊內(nèi)存空間,也是所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機啟動時創(chuàng)建。堆主要用于存儲對象實例和數(shù)組,這也是 Java 垃圾回收器主要活動的區(qū)域。

在物理上,堆區(qū)可以處于分散的內(nèi)存空間中,但在邏輯上它被視為連續(xù)的。堆區(qū)在 JVM 啟動時創(chuàng)建,如果堆區(qū)的空間不足,將會拋出 OutOfMemoryError。

堆分為新生代(Young Generation)和老年代(Old Generation)。新生代又分為 Eden 區(qū)、From Survivor 區(qū)(簡稱 S0)、 To Survivor 區(qū)(簡稱 S1)。劃分這么多區(qū)域的目的是為了更好地回收內(nèi)存,或者更快地分配內(nèi)存。

新生代中各個區(qū)域的內(nèi)存占比分別是,Eden : S0 : S1 = 8 : 1 : 1

新創(chuàng)建的對象優(yōu)先在  Eden 區(qū)進行分配。當 Eden 區(qū)滿時,會觸發(fā)一次 Minor GC(新生代垃圾回收,也叫 Young GC),將仍然存活的對象從 Eden 區(qū)和 S0 區(qū)移動到 S1 區(qū),下次 Minor GC 處理情況類似,把存活的對象從 Eden 區(qū)和 S1 區(qū)移動到 S0 區(qū)。當 Survivor 區(qū)也滿了,還存活的對象會被移動到老年代。如果老年代也滿了,將會觸發(fā) Major GC(老年代垃圾回收,也叫 Old GC)。當老年代滿了,也可能觸發(fā) Full GC,F(xiàn)ull GC 會對整個堆內(nèi)存進行垃圾回收,包含新生代、老年代和方法區(qū)。Full GC 會導(dǎo)致較長的停頓時間,并且會消耗大量的系統(tǒng)資源。

5. 方法區(qū)

方法區(qū)(Method Area)與堆一樣,是所有線程共享的內(nèi)存區(qū)域,用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。

方法區(qū)只是 JVM 規(guī)范中定義的一個概念,針對 Hotspot 虛擬機,JDK8 之前使用永久代(Permanent Generation,簡稱 PermGen)實現(xiàn),JDK8 使用元空間(Metaspace)實現(xiàn)。

JDK8 之前可以通過 -XX:PermSize 和 -XX:MaxPermSize 來設(shè)置永久代大小,JDK8 之后,使用元空間替換了永久代,改為通過 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 來設(shè)置元空間大小。

運行時常量池

運行時常量池(Runtime Constant Pool)是方法區(qū)中的一部分,用于存儲編譯期間生成的各種字面量和符號引用。在Java程序運行時,JVM將編譯期生成的class文件中的常量池內(nèi)容讀取到運行時常量池中。

運行時常量池存儲了類和接口中的常量,包括字符串字面量、被聲明為final的常量值等。它還存儲了類和接口中的符號引用,如類和接口、字段和方法的引用等。

在JVM中,運行時常量池是線程安全的。每個線程都有一個自己的線程棧,其中包含了局部變量表,而這些局部變量表中所引用的對象都位于堆中。當一個線程需要引用運行時常量池中的常量時,JVM會先將常量值從運行時常量池中復(fù)制到線程棧的局部變量表中,然后再進行引用。

需要注意的是,在JDK8中,運行時常量池已經(jīng)被移動到元空間(Metaspace)中。元空間是在本地內(nèi)存中分配的,與JVM的堆內(nèi)存是分離的,因此不會受到Java堆大小的限制。


網(wǎng)頁名稱:面試必問,JVM內(nèi)存模型掃盲
網(wǎng)頁地址:http://m.jiaoqi3.com/article/djoecgd.html