国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū)

這篇具有很好參考價(jià)值的文章主要介紹了JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

系列文章目錄

第一章 運(yùn)行區(qū)實(shí)驗(yàn)



前言

JVM(Java虛擬機(jī))運(yùn)行區(qū)是Java程序在運(yùn)行過(guò)程中被JVM所管理的內(nèi)存區(qū)域。它包括了Java程序運(yùn)行時(shí)的堆(Heap)、棧(Stack)、方法區(qū)(Method Area)、本地方法棧(Native Method Stacks)、程序計(jì)數(shù)器和直接內(nèi)存(Direct Memory)等部分。
JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū),面試,Java基礎(chǔ),JVM,jvm,運(yùn)行時(shí)數(shù)據(jù)區(qū),內(nèi)存管理


一、堆(Heap)

堆(Heap)是Java程序運(yùn)行時(shí)用于動(dòng)態(tài)分配內(nèi)存的區(qū)域,也是Java垃圾收集器進(jìn)行垃圾回收的主要區(qū)域。堆內(nèi)存被所有線程共享。

以JDK8為例,堆(Heap)用來(lái)存放對(duì)象,幾乎所有(逃逸分析技術(shù),棧上分配、標(biāo)量替換)對(duì)象都在堆上分配,將Java堆細(xì)分的目的只是為了更好地回收內(nèi)存,或者更快地分配內(nèi)存,堆中沒有內(nèi)存分配對(duì)象,并且無(wú)法擴(kuò)展時(shí),會(huì)拋出OutOfMemoryError異常。

堆(Heap)一般管理新生代/Young區(qū) 、年老代(old區(qū)) 、String字符串常量池。

1.1、新生代/Young區(qū)

新生代里包含Eden區(qū) 與 Survival區(qū)2個(gè)區(qū)。

1.1.1、Eden區(qū)

Eden區(qū)位于Java堆的年輕代,是新對(duì)象分配內(nèi)存的地方,由于堆是所有線程共享的,因此在堆上分配內(nèi)存需要加鎖。而Sun JDK為提升效率,會(huì)為每個(gè)新建的線程在Eden上分配一塊獨(dú)立的空間由該線程獨(dú)享,這塊空間稱為TLAB(Thread Local Allocation Buffer)。在TLAB上分配內(nèi)存不需要加鎖,因此JVM在給線程中的對(duì)象分配內(nèi)存時(shí)會(huì)盡量在TLAB上分配。如果對(duì)象過(guò)大或TLAB用完,則仍然在堆上進(jìn)行分配。如果Eden區(qū)內(nèi)存也用完了,則會(huì)進(jìn)行一次Minor GC(young GC)。

1.1.2、Survival區(qū)

Survival區(qū)與Eden區(qū)相同都在Java堆的年輕代。Survival區(qū)有兩塊,一塊稱為from區(qū),另一塊為to區(qū),這兩個(gè)區(qū)是相對(duì)的,在發(fā)生一次Minor GC后,from區(qū)就會(huì)和to區(qū)互換。在發(fā)生Minor GC時(shí),Eden區(qū)和Survival from區(qū)會(huì)把一些仍然存活的對(duì)象復(fù)制進(jìn)Survival to區(qū),并清除內(nèi)存。Survival to區(qū)會(huì)把一些存活得足夠舊的對(duì)象移至年老代。

1.2、年老代(old區(qū))

年老代里存放的都是存活時(shí)間較久的,大小較大的對(duì)象,因此年老代使用標(biāo)記整理算法。當(dāng)年老代容量滿的時(shí)候,會(huì)觸發(fā)一次Major GC(full GC),回收年老代和年輕代中不再被使用的對(duì)象資源

二、虛擬機(jī)棧(Stack)

每個(gè)線程在創(chuàng)建時(shí)都會(huì)創(chuàng)建一個(gè)私有的JVM棧。每個(gè)方法執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量、操作數(shù)棧、常量池引用等信息。如下圖,棧幀1、棧幀2、棧幀3、棧幀N。
JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū),面試,Java基礎(chǔ),JVM,jvm,運(yùn)行時(shí)數(shù)據(jù)區(qū),內(nèi)存管理

2.1、棧頂緩存技術(shù)

解釋執(zhí)行狀態(tài)下,將訪問最頻繁的數(shù)據(jù)(程序計(jì)數(shù)器、棧頂)緩存在物理CPU的寄存器中,以此降低對(duì)內(nèi)存的讀/寫次數(shù),提升執(zhí)行引擎的執(zhí)行效率。

2.2、溢出

如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許深度,將拋出StackOverflowError異常;如果Java虛擬機(jī)棧容量可以動(dòng)態(tài)擴(kuò)展 ,當(dāng)棧擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存會(huì)拋出OutOfMemoryError異常。

發(fā)生StackOverflowError異常,使用死循環(huán)遞歸代碼可以復(fù)現(xiàn)。
JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū),面試,Java基礎(chǔ),JVM,jvm,運(yùn)行時(shí)數(shù)據(jù)區(qū),內(nèi)存管理
可以使用參數(shù)-Xss選項(xiàng)來(lái)設(shè)置線程的最大??臻g,例如-Xss265k

2.3、棧幀

棧的存儲(chǔ)單位為棧幀,線程上正在執(zhí)行的一個(gè)方法對(duì)應(yīng)一個(gè)棧幀,棧幀是一個(gè)內(nèi)存區(qū)塊,是一個(gè)數(shù)據(jù)集,維系著方法執(zhí)行過(guò)程中的各種數(shù)據(jù)信息。

每個(gè)棧幀包含五部分,分別包括局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈表(指向運(yùn)行時(shí)常量池的方法引用)、方法返回地址和一些額外信息。
JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū),面試,Java基礎(chǔ),JVM,jvm,運(yùn)行時(shí)數(shù)據(jù)區(qū),內(nèi)存管理

2.3.1、局部變量表(local variables)

  • 局部變量表定義為一個(gè)數(shù)字?jǐn)?shù)組,主要用于存儲(chǔ)方法參數(shù)和定義在方法體內(nèi)的局部變量,這些數(shù)據(jù)類型包括各種基本數(shù)據(jù)類型、對(duì)象引用(reference),以及returnAddress類型。

  • 由于局部變量表是線程的私有數(shù)據(jù),不存在線程的安全問題

  • 局部變量表所需容量大小在編譯器確定下來(lái)的,并保存在方法的Code屬性的maximum local variables數(shù)據(jù)項(xiàng)中。在方法運(yùn)行期間是不會(huì)改變局部變量表的大小的。

  • 局部變量表的變量只在當(dāng)前方法調(diào)用中有效的,當(dāng)方法調(diào)用結(jié)束后,隨著方法棧幀的消耗,局部變量表也會(huì)隨之銷毀。

  • 局部變量表的最基本存儲(chǔ)單位是Slot(變量槽),32位以內(nèi)的類型只占用一個(gè)slot(包括returnAddress類型,引用類型),64位的類型(long和double)占用兩個(gè)slot。

  • 每一slot都分配一個(gè)訪問索引,占用兩個(gè)slot的變量,只需要使用前一個(gè)索引即可

  • 構(gòu)造方法或者實(shí)例方法(非static),該對(duì)象引用this將會(huì)存放在index為0的slot處

  • 局部變量表的變量也是重要的垃圾回收根節(jié)點(diǎn),只要被局部變量表中直接或間接引用的對(duì)象都不會(huì)被回收。

2.3.2、操作數(shù)棧(Operand Stack LIFO)

  • 編譯后 .Class文件的Code屬性的max_stacks數(shù)據(jù)記錄操作數(shù)棧的最大深度
  • 操作數(shù)棧,在方法執(zhí)行過(guò)程中,根據(jù)字節(jié)碼指令,往棧中寫入數(shù)據(jù)或提取數(shù)據(jù),即入棧或者出棧,使用數(shù)組實(shí)現(xiàn)
  • 操作數(shù)棧,主要用于保存計(jì)算過(guò)程的中間結(jié)果,同時(shí)作為計(jì)算過(guò)程中變量臨時(shí)的存儲(chǔ)空間。

2.3.3、動(dòng)態(tài)鏈接

運(yùn)行期間把常量池中的符號(hào)引用轉(zhuǎn)換成直接引用的過(guò)程,叫做動(dòng)態(tài)鏈接;
每個(gè)棧幀都包含一個(gè)指向運(yùn)行時(shí)常量池中該棧幀所屬方法的引用,持有這個(gè)引用是為了支持方法調(diào)用過(guò)程中的動(dòng)態(tài)鏈接。

2.3.4、方法返回地址

方法返回地址存儲(chǔ)的是調(diào)用該方法的pc寄存器的值。方法正常退出時(shí),調(diào)用者的pc計(jì)數(shù)器的值作為返回地址,即調(diào)用該方法的指令的下一條指令的地址。

2.3.5、額外信息

Java虛擬機(jī)規(guī)范,允許虛擬機(jī)實(shí)現(xiàn),在棧幀之中增加一些規(guī)范里沒有描述的信息,例如與調(diào)試、性能收集相關(guān)的信息。

三、方法區(qū)(MetaData Space)

方法區(qū)(MetaData Space 元空間)/Non-Heap,用于存儲(chǔ)已被JVM加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū),面試,Java基礎(chǔ),JVM,jvm,運(yùn)行時(shí)數(shù)據(jù)區(qū),內(nèi)存管理

3.1、方法區(qū)和永久代的關(guān)系

在JDK1.8之前,習(xí)慣把方法區(qū)稱為“永久代”。HotSpot 虛擬機(jī)在1.7之前使用永久代來(lái)管理(實(shí)現(xiàn))方法區(qū),使得jvm的垃圾回收器能像管理堆內(nèi)存一樣來(lái)管理永久代這部分內(nèi)存,而不用專門為方法區(qū)編寫內(nèi)存管理代碼。但這種設(shè)計(jì)使得虛擬機(jī)更容易出現(xiàn)內(nèi)存溢出問題,而不像J9和JRockit只要沒有觸碰到進(jìn)程可用內(nèi)存的上限(32位4GB),就沒有問題。
JDK1.7把原本放在永久代的字符串常量池、靜態(tài)變量等移出(主要剩余類型信息)
JDK1.8完全廢棄了永久代的概念,改用與JRockit、J9一樣,在本地內(nèi)存中實(shí)現(xiàn)的元空間方法區(qū)無(wú)法滿足新的內(nèi)存分配需求時(shí),將拋出OutOfMemoryError異常。

四、本地方法棧(Native Method Stacks)

Native Method Stacks 為虛擬機(jī)使用到的本地(Native)方法服務(wù),本地方法棧也會(huì)在棧深度溢出或者棧擴(kuò)展失敗時(shí)分別拋出StackOverflowError和OutOfMemoryError異常。

五、程序計(jì)數(shù)器

程序計(jì)數(shù)器,當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,字節(jié)碼解釋器工作時(shí),通過(guò)改變計(jì)數(shù)器的值,執(zhí)行下一條指令,此內(nèi)存是JVM規(guī)范中唯一一個(gè)沒有OutOfMemoryError的區(qū)域。

六、直接內(nèi)存(Direct Memory)

DM并不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分,也不是《Java虛擬機(jī)規(guī)范》中定義的內(nèi)存區(qū)域。但是這部分內(nèi)存也被頻繁地使用,而且也可能導(dǎo)致OutOfMemoryError異常出現(xiàn),例如:NIO 中的 DirectByteBuffer 直接操作堆外內(nèi)存,避免在Java堆和Native堆中來(lái)回復(fù)制數(shù)據(jù)。

同時(shí)也可以關(guān)注零拷貝(DMA)技術(shù)的應(yīng)用。


總結(jié)

這些內(nèi)存區(qū)域的管理和優(yōu)化對(duì)于Java程序的性能和可靠性至關(guān)重要。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-712606.html

到了這里,關(guān)于JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【面試題】JDK(工具包)、JRE(運(yùn)行環(huán)境和基礎(chǔ)庫(kù))、JVM(java虛擬機(jī))之間的關(guān)系?

    【面試題】JDK(工具包)、JRE(運(yùn)行環(huán)境和基礎(chǔ)庫(kù))、JVM(java虛擬機(jī))之間的關(guān)系?

    【面試題】JDK、JRE、JVM之間的關(guān)系? JDK (Java Development Kit):Java開發(fā)工具包,提供給Java程序員使用,包含了JRE,同時(shí)還包含了編譯器javac與自帶的調(diào)試工具Jconsole、jstack等。 JRE (Java Runtime Environment):Java運(yùn)行時(shí)環(huán)境,包含了JVM,Java基礎(chǔ)類庫(kù)。是使用Java語(yǔ)言編寫程序運(yùn)行的所需環(huán)境

    2024年02月11日
    瀏覽(34)
  • java八股文面試[JVM]——JVM內(nèi)存結(jié)構(gòu)

    java八股文面試[JVM]——JVM內(nèi)存結(jié)構(gòu)

    參考: JVM學(xué)習(xí)筆記(一)_卷心菜不卷Iris的博客-CSDN博客 JVM 是運(yùn)行在操作系統(tǒng)之上的,它與硬件沒有直接的交互 JVM內(nèi)存結(jié)構(gòu): ? 方法區(qū):存儲(chǔ)已被虛擬機(jī)加載的類元數(shù)據(jù)信息(元空間) 堆:存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例都在這里分配內(nèi)存 虛擬機(jī)棧:虛擬機(jī)棧描述的是

    2024年02月12日
    瀏覽(25)
  • JVM篇--Java內(nèi)存區(qū)域高頻面試題

    JVM篇--Java內(nèi)存區(qū)域高頻面試題

    首先我們要知道java堆空間的產(chǎn)生過(guò)程: 即當(dāng)通過(guò)java命令啟動(dòng)java進(jìn)程的時(shí)候,就會(huì)為它分配內(nèi)存,而分配內(nèi)存的一部分就會(huì)用于創(chuàng)建堆空間,而當(dāng)程序中創(chuàng)建對(duì)象的時(shí)候 就會(huì)從堆空間來(lái)分配內(nèi)存,所以堆空間存放的主要是對(duì)象和數(shù)組; 而GC 其實(shí)說(shuō)白了就是java虛擬機(jī)回收對(duì)象

    2024年02月01日
    瀏覽(57)
  • JVM內(nèi)存模型/運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    JVM內(nèi)存模型/運(yùn)行時(shí)數(shù)據(jù)區(qū)域

    java虛擬機(jī)管理這塊內(nèi)存,所以我們也叫運(yùn)行時(shí)數(shù)據(jù)區(qū)域 這里按線程是否共享來(lái)分類,所謂線程不共享就是每個(gè)線程里面都會(huì)配一套 程序計(jì)數(shù)器 棧, 互相不干涉。 而方法區(qū)和堆是線程所有共享 意味著只有一個(gè)(這里注意堆是實(shí)際概念 方法區(qū)是一個(gè)虛擬概念) 注意:程序計(jì)

    2024年01月18日
    瀏覽(25)
  • Java # JVM內(nèi)存管理

    程序計(jì)數(shù)器、Java虛擬機(jī)棧、本地方法棧、Java堆、方法區(qū)、運(yùn)行時(shí)常量池、直接內(nèi)存 對(duì)象創(chuàng)建: 引用檢查 類加載檢查 分配內(nèi)存空間:指針碰撞、空閑列表 分配空間初始化 對(duì)象信息設(shè)置(對(duì)象頭內(nèi)) 對(duì)象內(nèi)存布局: 對(duì)象頭 實(shí)例數(shù)據(jù) 對(duì)象填充 對(duì)象訪問定位: 句柄訪問 直接

    2024年02月13日
    瀏覽(18)
  • JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū)

    JVM系列 運(yùn)行時(shí)數(shù)據(jù)區(qū)

    第一章 運(yùn)行區(qū)實(shí)驗(yàn) JVM(Java虛擬機(jī))運(yùn)行區(qū)是Java程序在運(yùn)行過(guò)程中被JVM所管理的內(nèi)存區(qū)域。它包括了Java程序運(yùn)行時(shí)的堆(Heap)、棧(Stack)、方法區(qū)(Method Area)、本地方法棧(Native Method Stacks)、程序計(jì)數(shù)器和直接內(nèi)存(Direct Memory)等部分。 堆(Heap)是Java程序運(yùn)行時(shí)用于

    2024年02月08日
    瀏覽(12)
  • 深入探討Java虛擬機(jī)(JVM):執(zhí)行流程、內(nèi)存管理和垃圾回收機(jī)制

    深入探討Java虛擬機(jī)(JVM):執(zhí)行流程、內(nèi)存管理和垃圾回收機(jī)制

    目錄 什么是JVM? JVM 執(zhí)行流程 JVM 運(yùn)行時(shí)數(shù)據(jù)區(qū) 堆(線程共享) Java虛擬機(jī)棧(線程私有) 什么是線程私有? 程序計(jì)數(shù)器(線程私有) 方法區(qū)(線程共享) JDK 1.8 元空間的變化 運(yùn)行時(shí)常量池 內(nèi)存布局中的異常問題 1.? Java堆溢出 2.??虛擬機(jī)棧和本地方法棧溢出 JVM 類加載 1.

    2024年02月09日
    瀏覽(27)
  • JVM | 垃圾回收器(GC)- Java內(nèi)存管理的守護(hù)者

    JVM | 垃圾回收器(GC)- Java內(nèi)存管理的守護(hù)者

    在編程世界中, 有效的內(nèi)存管理 是至關(guān)重要的。這不僅確保了應(yīng)用程序的穩(wěn)定運(yùn)行,還可以大大提高性能和響應(yīng)速度。作為世界上最受歡迎的編程語(yǔ)言之一,通過(guò)Java虛擬機(jī)內(nèi)部的垃圾回收器組件來(lái)自動(dòng)管理內(nèi)存,是成為之一的其中一項(xiàng)必不可少的技術(shù)點(diǎn)。 在許多傳統(tǒng)的編程

    2024年02月09日
    瀏覽(29)
  • JVM零基礎(chǔ)到高級(jí)實(shí)戰(zhàn)之Java內(nèi)存區(qū)域本地方法棧

    JVM零基礎(chǔ)到高級(jí)實(shí)戰(zhàn)之Java內(nèi)存區(qū)域本地方法棧 JVM零基礎(chǔ)到高級(jí)實(shí)戰(zhàn)之Java內(nèi)存區(qū)域本地方法棧 本地方法棧是什么? 用于作用域本地方法執(zhí)行的一塊Java內(nèi)存區(qū)域 為什么要有本地方法棧? 與Java虛擬機(jī)棧相同,每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀(Stack Framel)用于存儲(chǔ)局部

    2024年02月09日
    瀏覽(13)
  • JAVA后端開發(fā)面試基礎(chǔ)知識(shí)(一)——JVM

    Class loader(類裝載) 根據(jù)給定的全限定名類名(如: java.lang.Object)來(lái)裝載class文件到 Runtime data area中的method area。 Execution engine(執(zhí)行引擎) 執(zhí)行classes中的指令。 Native Interface(本地接口) 與native libraries交互,是其它編程語(yǔ)言交互的接口。 Runtime data area(運(yùn)行時(shí)數(shù)據(jù)區(qū)域) 這就是我們常說(shuō)

    2024年03月10日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包