溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

發(fā)布時(shí)間:2021-09-02 13:46:18 來源:億速云 閱讀:171 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要為大家展示了“JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析”這篇文章吧。

    一、前言

    將對(duì)整個(gè)JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)和GC垃圾回收詳細(xì)的介紹

    二、運(yùn)行時(shí)數(shù)據(jù)區(qū)整體概架構(gòu)

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    以下是自己的一句話總結(jié):

    分為線程私有和線程共享的兩大類,其中程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧是屬于線程私有的,堆內(nèi)存及方法區(qū)內(nèi)存是線程共享的。程序計(jì)數(shù)器主要是記錄字節(jié)碼指令,CPU上下文切換線程,從一個(gè)線程切換到另一個(gè)線程,需要知道線程執(zhí)行到哪一步,所以記錄這個(gè)指令就是很有必要的,程序計(jì)數(shù)器無OOM和GC的發(fā)生。虛擬機(jī)棧里面是一個(gè)個(gè)棧幀,每一個(gè)棧幀對(duì)應(yīng)著每一個(gè)方法,棧幀又是由局部變量表、操作數(shù)棧、方法返回值地址、動(dòng)態(tài)鏈接組成。虛擬機(jī)棧可能會(huì)發(fā)生棧溢出異常,即starkoverflow本地方法棧是存放本地方法相關(guān)的東西;堆是一塊很大的空間,整體分為2大塊,新生代和老年代,新生代又分了Eden區(qū)、S0區(qū)、S1區(qū),垃圾回收主要發(fā)生在新生代,每一個(gè)區(qū)對(duì)應(yīng)不同的垃圾回收算法;方法區(qū)保存的是一些常量、類的基本信息等,方法區(qū)對(duì)應(yīng)的實(shí)現(xiàn)在JDK7中是永久代,在JDK8中是元空間。

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

    用來儲(chǔ)存指向下一條指令的地址,是線程私有的,生命周期和線程的生命周期一致。

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    四、虛擬機(jī)棧

    虛擬機(jī)棧是線程私有的,內(nèi)部保存一個(gè)個(gè)棧幀,每一個(gè)棧幀對(duì)應(yīng)一個(gè)Java方法的調(diào)用,生命周期和線程的生命周期保持一致。先來看看棧的特點(diǎn)。

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    1、棧的特點(diǎn)

    棧是運(yùn)行時(shí)的單位,而堆是存儲(chǔ)的單位。棧的特點(diǎn)是先進(jìn)后出,后進(jìn)先出。

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    可以通過參數(shù)-Xss來設(shè)置??臻g大小

    2、棧幀的內(nèi)部結(jié)構(gòu)

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    3、局部變量表

    是一個(gè)數(shù)字?jǐn)?shù)組,主要用于存儲(chǔ)方法參數(shù)和定義在方法內(nèi)的局部變量,這些數(shù)據(jù)類型包括各類基本數(shù)據(jù)類型,對(duì)象引用等,所需的容量大小是在編譯期確定下來的,在方法運(yùn)行期間是不會(huì)改變局部變量表大小的。

    關(guān)于Slot的理解:

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    靜態(tài)變量和局部變量的區(qū)別:

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    總結(jié):

    在棧幀中,與性能關(guān)系最為密切的就是局部變量表,在方法執(zhí)行時(shí),虛擬機(jī)使用局部變量表完成完成方法的傳遞,局部變量表中的數(shù)據(jù)也是可達(dá)性分析中的GC Root,如果一個(gè)對(duì)象在局部變量表中還有引用,那么根絕可達(dá)性分析算法,這個(gè)變量就不屬于垃圾對(duì)象,是不會(huì)被GC回收的。

    4、操作數(shù)棧

    操作數(shù)棧是棧中棧,也可稱為表達(dá)式棧,在方法執(zhí)行過程中,根據(jù)字節(jié)碼指令,往棧中寫入數(shù)據(jù)或提取數(shù)據(jù),即入棧和出棧。主要用于保存計(jì)算過程的中間結(jié)果。操作數(shù)棧,可以看成是臨時(shí)寄存器,計(jì)算過程中變量的臨時(shí)保存

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

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

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    方法重寫的本質(zhì)

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    6、方法返回地址

    存放調(diào)用該方法的PC寄存器的值

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    五、本地方法棧

    管理本地native本地方法,是線程私有的,所謂的本地方法,其實(shí)就是一些非Java語言寫的代碼,這部分代碼甚至可以和操作系統(tǒng)CPU進(jìn)行打交道。

    六、堆

    堆是內(nèi)存管理的核心區(qū)域,是線程共享的,屬于JVM級(jí)別,也就是一個(gè)JVM實(shí)例就會(huì)有一個(gè)堆空間,注意的是雖然堆整體上是線程共享的,但是在內(nèi)部有一小塊空間是線程私有的緩存區(qū)TLAB。

    幾乎所有的對(duì)象實(shí)例都是在堆中,堆是GC垃圾回收的重點(diǎn)區(qū)域。堆整體可以分為新生代和老年代,新生代又分為Eden區(qū)和S0和S1區(qū)。

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    新生代和老年代的比例是1:2,Eden區(qū)和s0,s1區(qū)所占空間比例是8:1:1

    1、設(shè)置堆大小的參數(shù)

    -Xms:用于表示堆區(qū)的起始內(nèi)存,默認(rèn)情況下,占物理內(nèi)存大小的64分之一。

    -Xmx用于表示堆區(qū)的最大內(nèi)存,默認(rèn)情況下,占物理內(nèi)存的四分之一。

    通常起始內(nèi)存和最大內(nèi)存兩個(gè)參數(shù)設(shè)置成一樣,目的是為了GC清理完堆區(qū)內(nèi)存后不需要重新分隔
    計(jì)算堆區(qū)的大小,從而提高性能。
    查看設(shè)置的參數(shù):
    方式一:jps(查看進(jìn)程)  
                jstat -gc 進(jìn)程id
    方式二:-xx:+printGCDetails

    2、對(duì)象分配過程

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    這里s0和s1誰是空的誰就是to,年齡計(jì)數(shù)器閾值是15,YGC是在Eden區(qū)滿的時(shí)候會(huì)觸發(fā),s0和s1滿的時(shí)候不會(huì)觸發(fā)YGC,YGC會(huì)將s區(qū)以及伊甸園區(qū)一起GC

    關(guān)于垃圾回收,頻繁在新生區(qū)收集,很少在養(yǎng)老區(qū)收集,幾乎不在永久區(qū)/元空間收集。

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    Visualvm是JVM常用調(diào)優(yōu)工具,在JDK的bin下就可以打開

    3、堆中的GC

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    年輕代(Minor GC)觸發(fā)機(jī)制

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    老年代GC(Major GC/Full GC)觸發(fā)機(jī)制

    Full GC 觸發(fā)機(jī)制

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    4、內(nèi)存分配策略

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    5、什么是TLAB

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    TLAB表明堆不一定是共享的。

    6、堆是分配對(duì)象存儲(chǔ)的唯一選擇嗎?

    如果經(jīng)過逃逸分析,一個(gè)對(duì)象并沒有逃逸出方法的話,那么就有可能被優(yōu)化成棧上分配。

    逃逸分析手段:

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    注意:JDK6U23版本后,HotSpot默認(rèn)已經(jīng)開啟逃逸分析。所以我們得出一個(gè)結(jié)論,開發(fā)中能使用局部變量的,就不要使用在方法外定義。JDK7后字符串常量池和靜態(tài)變量存儲(chǔ)在堆中

    七、方法區(qū)

    方法區(qū)可以看做是一塊獨(dú)立于堆的內(nèi)存空間,是線程共享的,主要存儲(chǔ)類信息、運(yùn)行時(shí)常量池等,也會(huì)發(fā)生OOM,JDK8前成為永久代,JDK8成為元空間。(元空間和永久代最大的區(qū)別是,元空間不再使用JVM內(nèi)存,而是使用了本地內(nèi)存技術(shù))

    1、方法區(qū)概述

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    2、設(shè)置方法區(qū)內(nèi)存大小

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    3、如何解決OOM問題?

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    4、方法區(qū)存儲(chǔ)什么

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    5、方法區(qū)的演進(jìn)細(xì)節(jié)

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    6、方法區(qū)的GC

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析

    以上是“JAVA中JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI