日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

面試官:說說JVM內(nèi)存整體結(jié)構(gòu)?線程私有還是共享的?

來源: 責(zé)編: 時間:2024-01-02 17:28:37 253觀看
導(dǎo)讀JVM 整體架構(gòu),中間部分就是 Java 虛擬機定義的各種運行時數(shù)據(jù)區(qū)域。圖片Java 虛擬機定義了若干種程序運行期間會使用到的運行時數(shù)據(jù)區(qū),其中有一些會隨著虛擬機啟動而創(chuàng)建,隨著虛擬機退出而銷毀。另外一些則是與線程一一

JVM 整體架構(gòu),中間部分就是 Java 虛擬機定義的各種運行時數(shù)據(jù)區(qū)域。djj28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片djj28資訊網(wǎng)——每日最新資訊28at.com

Java 虛擬機定義了若干種程序運行期間會使用到的運行時數(shù)據(jù)區(qū),其中有一些會隨著虛擬機啟動而創(chuàng)建,隨著虛擬機退出而銷毀。另外一些則是與線程一一對應(yīng)的,這些與線程一一對應(yīng)的數(shù)據(jù)區(qū)域會隨著線程開始和結(jié)束而創(chuàng)建和銷毀。djj28資訊網(wǎng)——每日最新資訊28at.com

線程私有:程序計數(shù)器、虛擬機棧、本地方法區(qū)djj28資訊網(wǎng)——每日最新資訊28at.com

線程共享:堆、方法區(qū), 堆外內(nèi)存(Java7的永久代或JDK8的元空間、代碼緩存)djj28資訊網(wǎng)——每日最新資訊28at.com

什么是程序計數(shù)器(線程私有)?
djj28資訊網(wǎng)——每日最新資訊28at.com

PC 寄存器用來存儲指向下一條指令的地址,即將要執(zhí)行的指令代碼。由執(zhí)行引擎讀取下一條指令。djj28資訊網(wǎng)——每日最新資訊28at.com

PC寄存器為什么會被設(shè)定為線程私有的?

多線程在一個特定的時間段內(nèi)只會執(zhí)行其中某一個線程方法,CPU會不停的做任務(wù)切換,這樣必然會導(dǎo)致經(jīng)常中斷或恢復(fù)。為了能夠準確的記錄各個線程正在執(zhí)行的當前字節(jié)碼指令地址,所以為每個線程都分配了一個PC寄存器,每個線程都獨立計算,不會互相影響。djj28資訊網(wǎng)——每日最新資訊28at.com

什么是虛擬機棧(線程私有)?

主管 Java 程序的運行,它保存方法的局部變量、部分結(jié)果,并參與方法的調(diào)用和返回。每個線程在創(chuàng)建的時候都會創(chuàng)建一個虛擬機棧,其內(nèi)部保存一個個的棧幀(Stack Frame),對應(yīng)著一次次 Java 方法調(diào)用,是線程私有的,生命周期和線程一致。djj28資訊網(wǎng)——每日最新資訊28at.com

特點?djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 棧是一種快速有效的分配存儲方式,訪問速度僅次于程序計數(shù)器
  2. JVM 直接對虛擬機棧的操作只有兩個:每個方法執(zhí)行,伴隨著入棧(進棧/壓棧),方法執(zhí)行結(jié)束出棧
  3. 棧不存在垃圾回收問題
  4. 可以通過參數(shù)-Xss來設(shè)置線程的最大棧空間,棧的大小直接決定了函數(shù)調(diào)用的最大可達深度

該區(qū)域有哪些異常?djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 如果采用固定大小的 Java 虛擬機棧,那每個線程的 Java 虛擬機棧容量可以在線程創(chuàng)建的時候獨立選定。如果線程請求分配的棧容量超過 Java 虛擬機棧允許的最大容量,Java 虛擬機將會拋出一個 StackOverflowError 異常
  2. 如果 Java 虛擬機棧可以動態(tài)擴展,并且在嘗試擴展的時候無法申請到足夠的內(nèi)存,或者在創(chuàng)建新的線程時沒有足夠的內(nèi)存去創(chuàng)建對應(yīng)的虛擬機棧,那 Java 虛擬機將會拋出一個OutOfMemoryError異常

棧幀的內(nèi)部結(jié)構(gòu)?djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 局部變量表(Local Variables)
  2. 操作數(shù)棧(Operand Stack)(或稱為表達式棧)
  3. 動態(tài)鏈接(Dynamic Linking):指向運行時常量池的方法引用
  4. 方法返回地址(Return Address):方法正常退出或異常退出的地址
  5. 一些附加信息

圖片圖片djj28資訊網(wǎng)——每日最新資訊28at.com

Java虛擬機棧如何進行方法計算的?

以如下代碼為例:djj28資訊網(wǎng)——每日最新資訊28at.com

private static int add(int a, int b) {    int c = 0;    c = a + b;    return c;}

可以通過jsclass 等工具查看bytecodedjj28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片djj28資訊網(wǎng)——每日最新資訊28at.com

壓棧的步驟如下:djj28資訊網(wǎng)——每日最新資訊28at.com

0:   iconst_0 // 0壓棧1:   istore_2 // 彈出int,存放于局部變量22:   iload_0  // 把局部變量0壓棧3:   iload_1  // 局部變量1壓棧4:   iadd     //彈出2個變量,求和,結(jié)果壓棧5:   istore_2 //彈出結(jié)果,放于局部變量26:   iload_2  //局部變量2壓棧7:   ireturn  //返回

如果計算100+98的值,那么操作數(shù)棧的變化如下圖:djj28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片djj28資訊網(wǎng)——每日最新資訊28at.com

什么是本地方法棧(線程私有)?

  • 本地方法接口

一個 Native Method 就是一個 Java 調(diào)用非 Java 代碼的接口。我們知道的 Unsafe 類就有很多本地方法。djj28資訊網(wǎng)——每日最新資訊28at.com

  • 本地方法棧(Native Method Stack)

Java 虛擬機棧用于管理 Java 方法的調(diào)用,而本地方法棧用于管理本地方法的調(diào)用djj28資訊網(wǎng)——每日最新資訊28at.com

什么是方法區(qū)(線程共享)?

方法區(qū)(method area)只是 JVM 規(guī)范中定義的一個概念,用于存儲類信息、常量池、靜態(tài)變量、JIT編譯后的代碼等數(shù)據(jù),并沒有規(guī)定如何去實現(xiàn)它,不同的廠商有不同的實現(xiàn)。而永久代(PermGen)**是 **Hotspot** 虛擬機特有的概念, Java8 的時候又被**元空間取代了,永久代和元空間都可以理解為方法區(qū)的落地實現(xiàn)。djj28資訊網(wǎng)——每日最新資訊28at.com

JDK1.8之前調(diào)節(jié)方法區(qū)大小:djj28資訊網(wǎng)——每日最新資訊28at.com

-XX:PermSize=N //方法區(qū)(永久代)初始大小-XX:MaxPermSize=N //方法區(qū)(永久代)最大大小,超出這個值將會拋出OutOfMemoryError

JDK1.8開始方法區(qū)(HotSpot的永久代)被徹底刪除了,取而代之的是元空間,元空間直接使用的是本機內(nèi)存。參數(shù)設(shè)置:djj28資訊網(wǎng)——每日最新資訊28at.com

-XX:MetaspaceSize=N //設(shè)置Metaspace的初始(和最小大小)-XX:MaxMetaspaceSize=N //設(shè)置Metaspace的最大大小

棧、堆、方法區(qū)的交互關(guān)系

圖片圖片djj28資訊網(wǎng)——每日最新資訊28at.com

永久代和元空間內(nèi)存使用上的差異?

Java虛擬機規(guī)范中只定義了方法區(qū)用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量和即時編譯后的代碼等數(shù)據(jù)djj28資訊網(wǎng)——每日最新資訊28at.com

  1. jdk1.7開始符號引用存儲在native heap中,字符串常量和靜態(tài)類型變量存儲在普通的堆區(qū)中,但分離的并不徹底,此時永久代中還保存另一些與類的元數(shù)據(jù)無關(guān)的雜項
  2. jdk8后HotSpot 原永久代中存儲的類的元數(shù)據(jù)將存儲在metaspace中,而類的靜態(tài)變量和字符串常量將放在Java堆中,metaspace是方法區(qū)的一種實現(xiàn),只不過它使用的不是虛擬機內(nèi)的內(nèi)存,而是本地內(nèi)存。在元空間中保存的數(shù)據(jù)比永久代中純粹很多,就只是類的元數(shù)據(jù),這些信息只對編譯期或JVM的運行時有用。
  3. 永久代有一個JVM本身設(shè)置固定大小上線,無法進行調(diào)整,而元空間使用的是直接內(nèi)存,受本機可用內(nèi)存的限制,并且永遠不會得到j(luò)ava.lang.OutOfMemoryError。
  4. 符號引用沒有存在元空間中,而是存在native heap中,這是兩個方式和位置,不過都可以算作是本地內(nèi)存,在虛擬機之外進行劃分,沒有設(shè)置限制參數(shù)時只受物理內(nèi)存大小限制,即只有占滿了操作系統(tǒng)可用內(nèi)存后才OOM。

堆區(qū)內(nèi)存是怎么細分的?

對于大多數(shù)應(yīng)用,Java 堆是 Java 虛擬機管理的內(nèi)存中最大的一塊,被所有線程共享。此內(nèi)存區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例以及數(shù)據(jù)都在這里分配內(nèi)存。djj28資訊網(wǎng)——每日最新資訊28at.com

為了進行高效的垃圾回收,虛擬機把堆內(nèi)存邏輯上劃分成三塊區(qū)域(分代的唯一理由就是優(yōu)化 GC 性能):djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 新生帶(年輕代):新對象和沒達到一定年齡的對象都在新生代
  2. 老年代(養(yǎng)老區(qū)):被長時間使用的對象,老年代的內(nèi)存空間應(yīng)該要比年輕代更大

 djj28資訊網(wǎng)——每日最新資訊28at.com

圖片djj28資訊網(wǎng)——每日最新資訊28at.com

Java 虛擬機規(guī)范規(guī)定,Java 堆可以是處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的即可,像磁盤空間一樣。實現(xiàn)時,既可以是固定大小,也可以是可擴展的,主流虛擬機都是可擴展的(通過 -Xmx 和 -Xms 控制),如果堆中沒有完成實例分配,并且堆無法再擴展時,就會拋出 OutOfMemoryError 異常。djj28資訊網(wǎng)——每日最新資訊28at.com

  • 年輕代 (Young Generation)

年輕代是所有新對象創(chuàng)建的地方。當填充年輕代時,執(zhí)行垃圾收集。這種垃圾收集稱為 Minor GC。年輕一代被分為三個部分——伊甸園(Eden Memory)和兩個幸存區(qū)(Survivor Memory,被稱為from/to或s0/s1),默認比例是8:1:1djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 大多數(shù)新創(chuàng)建的對象都位于 Eden 內(nèi)存空間中
  2. 當 Eden 空間被對象填充時,執(zhí)行Minor GC,并將所有幸存者對象移動到一個幸存者空間中
  3. Minor GC 檢查幸存者對象,并將它們移動到另一個幸存者空間。所以每次,一個幸存者空間總是空的
  4. 經(jīng)過多次 GC 循環(huán)后存活下來的對象被移動到老年代。通常,這是通過設(shè)置年輕一代對象的年齡閾值來實現(xiàn)的,然后他們才有資格提升到老一代
  • 老年代(Old Generation)

舊的一代內(nèi)存包含那些經(jīng)過許多輪小型 GC 后仍然存活的對象。通常,垃圾收集是在老年代內(nèi)存滿時執(zhí)行的。老年代垃圾收集稱為 主GC(Major GC),通常需要更長的時間。djj28資訊網(wǎng)——每日最新資訊28at.com

大對象直接進入老年代(大對象是指需要大量連續(xù)內(nèi)存空間的對象)。這樣做的目的是避免在 Eden 區(qū)和兩個Survivor 區(qū)之間發(fā)生大量的內(nèi)存拷貝djj28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片djj28資訊網(wǎng)——每日最新資訊28at.com

JVM中對象在堆中的生命周期?

  1. 在 JVM 內(nèi)存模型的堆中,堆被劃分為新生代和老年代

新生代又被進一步劃分為 Eden區(qū) 和 Survivor區(qū),Survivor 區(qū)由 From Survivor 和 To Survivor 組成djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 當創(chuàng)建一個對象時,對象會被優(yōu)先分配到新生代的 Eden 區(qū)

此時 JVM 會給對象定義一個對象年輕計數(shù)器(-XX:MaxTenuringThreshold)djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 當 Eden 空間不足時,JVM 將執(zhí)行新生代的垃圾回收(Minor GC)

JVM 會把存活的對象轉(zhuǎn)移到 Survivor 中,并且對象年齡 +1djj28資訊網(wǎng)——每日最新資訊28at.com

對象在 Survivor 中同樣也會經(jīng)歷 Minor GC,每經(jīng)歷一次 Minor GC,對象年齡都會+1djj28資訊網(wǎng)——每日最新資訊28at.com

  1. 如果分配的對象超過了-XX:PetenureSizeThreshold,對象會直接被分配到老年代

JVM中對象的分配過程?

為對象分配內(nèi)存是一件非常嚴謹和復(fù)雜的任務(wù),JVM 的設(shè)計者們不僅需要考慮內(nèi)存如何分配、在哪里分配等問題,并且由于內(nèi)存分配算法和內(nèi)存回收算法密切相關(guān),所以還需要考慮 GC 執(zhí)行完內(nèi)存回收后是否會在內(nèi)存空間中產(chǎn)生內(nèi)存碎片。djj28資訊網(wǎng)——每日最新資訊28at.com

  1. new 的對象先放在伊甸園區(qū),此區(qū)有大小限制
  2. 當伊甸園的空間填滿時,程序又需要創(chuàng)建對象,JVM 的垃圾回收器將對伊甸園區(qū)進行垃圾回收(Minor GC),將伊甸園區(qū)中的不再被其他對象所引用的對象進行銷毀。再加載新的對象放到伊甸園區(qū)
  3. 然后將伊甸園中的剩余對象移動到幸存者 0 區(qū)
  4. 如果再次觸發(fā)垃圾回收,此時上次幸存下來的放到幸存者 0 區(qū),如果沒有回收,就會放到幸存者 1 區(qū)
  5. 如果再次經(jīng)歷垃圾回收,此時會重新放回幸存者 0 區(qū),接著再去幸存者 1 區(qū)
  6. 什么時候才會去養(yǎng)老區(qū)呢?默認是 15 次回收標記
  7. 在養(yǎng)老區(qū),相對悠閑。當養(yǎng)老區(qū)內(nèi)存不足時,再次觸發(fā) Major GC,進行養(yǎng)老區(qū)的內(nèi)存清理
  8. 若養(yǎng)老區(qū)執(zhí)行了 Major GC 之后發(fā)現(xiàn)依然無法進行對象的保存,就會產(chǎn)生 OOM 異常

什么是 TLAB (Thread Local Allocation Buffer)?

  • 從內(nèi)存模型而不是垃圾回收的角度,對 Eden 區(qū)域繼續(xù)進行劃分,JVM 為每個線程分配了一個私有緩存區(qū)域,它包含在 Eden 空間內(nèi)
  • 多線程同時分配內(nèi)存時,使用 TLAB 可以避免一系列的非線程安全問題,同時還能提升內(nèi)存分配的吞吐量,因此我們可以將這種內(nèi)存分配方式稱為快速分配策略
  • OpenJDK 衍生出來的 JVM 大都提供了 TLAB 設(shè)計

為什么要有 TLAB ?

  • 堆區(qū)是線程共享的,任何線程都可以訪問到堆區(qū)中的共享數(shù)據(jù)
  • 由于對象實例的創(chuàng)建在 JVM 中非常頻繁,因此在并發(fā)環(huán)境下從堆區(qū)中劃分內(nèi)存空間是線程不安全的
  • 為避免多個線程操作同一地址,需要使用加鎖等機制,進而影響分配速度

盡管不是所有的對象實例都能夠在 TLAB 中成功分配內(nèi)存,但 JVM 確實是將 TLAB 作為內(nèi)存分配的首選。djj28資訊網(wǎng)——每日最新資訊28at.com

在程序中,可以通過 -XX:UseTLAB 設(shè)置是否開啟 TLAB 空間。djj28資訊網(wǎng)——每日最新資訊28at.com

默認情況下,TLAB 空間的內(nèi)存非常小,僅占有整個 Eden 空間的 1%,我們可以通過 -XX:TLABWasteTargetPercent 設(shè)置 TLAB 空間所占用 Eden 空間的百分比大小。djj28資訊網(wǎng)——每日最新資訊28at.com

一旦對象在 TLAB 空間分配內(nèi)存失敗時,JVM 就會嘗試著通過使用加鎖機制確保數(shù)據(jù)操作的原子性,從而直接在 Eden 空間中分配內(nèi)存。djj28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-56427-0.html面試官:說說JVM內(nèi)存整體結(jié)構(gòu)?線程私有還是共享的?

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Go 語言為什么很少使用數(shù)組?

下一篇: 簡聊Fastapi框架中的OpenAPI規(guī)范

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 荥经县| 镇宁| 道孚县| SHOW| 绥德县| 沁阳市| 慈利县| 资源县| 寿光市| 仁怀市| 东兰县| 彭山县| 当涂县| 伊金霍洛旗| 鹤山市| 吉林省| 庄浪县| 富顺县| 营口市| 平凉市| 万荣县| 全州县| 丹棱县| 井研县| 股票| 屯留县| 通许县| 永川市| 崇阳县| 吉首市| 聂荣县| 佛学| 象州县| 太和县| 五原县| 马关县| 巫溪县| 忻州市| 获嘉县| 青海省| 长岛县|