最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JVM內(nèi)存劃分機(jī)制的使用詳解

 更新時(shí)間:2025年05月04日 22:09:42   作者:棕豆兔&  
這篇文章主要介紹了JVM內(nèi)存劃分機(jī)制的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、JVM 執(zhí)行流程

程序在執(zhí)行之前先要把 java 代碼轉(zhuǎn)換成字節(jié)碼(class文件),JVM 首先需要把字節(jié)碼通過一定的方式:類加載器(ClassLoader) 把文件加載到內(nèi)存中運(yùn)行時(shí)數(shù)據(jù)區(qū)(Runtime Data Area),而字節(jié)碼文件是 JVM 的一套指令集規(guī)范,并不能直接交個(gè)底層操作系統(tǒng)去執(zhí)行,因此需要特定的命令解析器 “執(zhí)行引擎(Execution Engine)”將字節(jié)碼翻譯成底層系統(tǒng)指令再交由CPU去執(zhí)行,而這個(gè)過程中需要調(diào)用其他語言的接口,本地庫接口(Native Interface) 來實(shí)現(xiàn)整個(gè)程序的功能,這就是這4個(gè)主要組成部分的職責(zé)與功能。

總結(jié)來看,JVM 主要通過分為以下 4 個(gè)部分,來執(zhí)行 Java 程序的:

  1. 類加載器(ClassLoader)
  2. 運(yùn)行時(shí)數(shù)據(jù)區(qū)(Runtime Data Area)
  3. 執(zhí)行引擎(Execution Engine)
  4. 本地庫接口(Native Interface)

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

JVM 運(yùn)行時(shí)數(shù)據(jù)區(qū)域也叫內(nèi)存布局,但需要注意的是它和 Java 內(nèi)存模型((Java Memory Model,簡(jiǎn)稱 JMM)完全不同,屬于完全不同的兩個(gè)概念,它由以下 5 大部分組成:

2.1 堆(線程共享)

堆的作用:程序中創(chuàng)建的所有對(duì)象都在保存在堆中。

我們常見的 JVM 參數(shù)設(shè)置 -Xms10m 最小啟動(dòng)內(nèi)存是針對(duì)堆的,-Xmx10m 最大運(yùn)行內(nèi)存也是針對(duì)堆的。

ms 是 memory start 簡(jiǎn)稱,mx 是 memory max 的簡(jiǎn)稱。

堆里面分為兩個(gè)區(qū)域:新生代和老生代,新生代放新建的對(duì)象,當(dāng)經(jīng)過一定 GC 次數(shù)之后還存活的對(duì)象會(huì)放入老生代。新生代還有 3 個(gè)區(qū)域:一個(gè) Endn + 兩個(gè) Survivor(S0/S1)。

垃圾回收的時(shí)候會(huì)將 Endn 中存活的對(duì)象放到一個(gè)未使用的 Survivor 中,并把當(dāng)前的 Endn 和正在使用的 Survivor 清楚掉。

2.2 Java虛擬機(jī)棧(線程私有)

Java 虛擬機(jī)棧的作用:Java 虛擬機(jī)棧的生命周期和線程相同,Java 虛擬機(jī)棧描述的是 Java 方法執(zhí)行的內(nèi)存模型:每個(gè)方法在執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。常說的堆內(nèi)存、棧內(nèi)存中,棧內(nèi)存指的就是虛擬機(jī)棧。 Java 虛擬機(jī)棧中包含了以下 4 部分:

  1. 局部變量表: 存放了編譯器可知的各種基本數(shù)據(jù)類型(8大基本數(shù)據(jù)類型)、對(duì)象引用。局部變量表所需的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個(gè)方法時(shí),這個(gè)方法需要在幀中分配多大的局部變量空間是完全確定的,在執(zhí)行期間不會(huì)改變局部變量表大小。簡(jiǎn)單來說就是存放方法參數(shù)和局部變量。
  2. 操作棧:每個(gè)方法會(huì)生成一個(gè)先進(jìn)后出的操作棧。
  3. 動(dòng)態(tài)鏈接:指向運(yùn)行時(shí)常量池的方法引用。
  4. 方法返回地址:PC 寄存器的地址。

什么是線程私有?

由于JVM的多線程是通過線程輪流切換并分配處理器執(zhí)行時(shí)間的方式來實(shí)現(xiàn),因此在任何一個(gè)確定的時(shí)刻,一個(gè)處理器(多核處理器則指的是一個(gè)內(nèi)核)都只會(huì)執(zhí)行一條線程中的指令。因此為了切換線程后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要獨(dú)立的程序計(jì)數(shù)器,各條線程之間計(jì)數(shù)器互不影響,獨(dú)立存儲(chǔ)。我們就把類似這類區(qū)域稱之為"線程私有"的內(nèi)存。

2.3 本地方法棧(線程私有)

本地方法棧和虛擬機(jī)棧類似,只不過 Java 虛擬機(jī)棧是給 JVM 使用的,而本地方法棧是給本地方法使用的。

2.4 程序計(jì)數(shù)器(線程私有)

程序計(jì)數(shù)器的作用:用來記錄當(dāng)前線程執(zhí)行的行號(hào)的。

程序計(jì)數(shù)器是一塊比較小的內(nèi)存空間,可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。 如果當(dāng)前線程正在執(zhí)行的是一個(gè)Java方法,此計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址;如果正在執(zhí)行的是一個(gè)Native方法,這個(gè)計(jì)數(shù)器值為空。

程序計(jì)數(shù)器內(nèi)存區(qū)域是唯一一個(gè)在JVM規(guī)范中沒有規(guī)定任何OOM情況的區(qū)域!

2.5 方法區(qū)(線程共享)

方法區(qū)的作用:用來存儲(chǔ)被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)的。

在《Java虛擬機(jī)規(guī)范中》把此區(qū)域稱之為“方法區(qū)”,而在 HotSpot 虛擬機(jī)的實(shí)現(xiàn)中,在 JDK 7 時(shí)此區(qū)域叫做永久代(PermGen),JDK 8 中叫做元空間(Metaspace)。

JDK 1.8 元空間的變化:

  • 對(duì)于 HotSpot 來說,JDK 8 元空間的內(nèi)存屬于本地內(nèi)存,這樣元空間的大小就不在受 JVM 最大內(nèi)存的參數(shù)影響了,而是與本地內(nèi)存的大小有關(guān)。
  • JDK 8 中將字符串常量池移動(dòng)到了堆中。

2.6 運(yùn)行時(shí)常量池

運(yùn)行時(shí)常量池是方法區(qū)的一部分,存放字面量與符號(hào)引用。

  • 字面量 : 字符串(JDK 8 移動(dòng)到堆中) 、final常量、基本數(shù)據(jù)類型的值。
  • 符號(hào)引用 : 類和結(jié)構(gòu)的完全限定名、字段的名稱和描述符、方法的名稱和描述符。

三、內(nèi)存布局中的異常問題

3.1 Java堆溢出

Java堆用于存儲(chǔ)對(duì)象實(shí)例,只要不斷的創(chuàng)建對(duì)象,并且保證GC Roots到對(duì)象之間有可達(dá)路徑來避免來 GC 清除這些對(duì)象,那么在對(duì)象數(shù)量達(dá)到最大堆容量后就會(huì)產(chǎn)生內(nèi)存溢出異常。

Java堆內(nèi)存的OOM異常是實(shí)際應(yīng)用中最常見的內(nèi)存溢出情況。當(dāng)出現(xiàn)Java堆內(nèi)存溢出時(shí),異常堆棧信息"java.lang.OutOfMemoryError"會(huì)進(jìn)一步提示"Java heap space"。當(dāng)出現(xiàn)"Java heap space"則很明確的告知我們,OOM發(fā)生在堆上。

此時(shí)要對(duì)Dump出來的文件進(jìn)行分析,以MAT為例。分析問題的產(chǎn)生到底是出現(xiàn)了內(nèi)存泄漏(Memory Leak)還是內(nèi)存溢出(Memory Overflow)

  • 內(nèi)存泄漏 : 泄漏對(duì)象無法被GC。
  • 內(nèi)存溢出 : 內(nèi)存對(duì)象確實(shí)還應(yīng)該存活。此時(shí)要根據(jù)JVM堆參數(shù)與物理內(nèi)存相比較檢查是否還應(yīng)該把JVM 堆內(nèi)存調(diào)大;或者檢查對(duì)象的生命周期是否過長。

3.2 虛擬機(jī)棧和本地方法棧溢出

由于HotSpot虛擬機(jī)將虛擬機(jī)棧與本地方法棧合二為一,因此對(duì)于HotSpot來說,棧容量只需要由-Xss參數(shù)來設(shè)置。

關(guān)于虛擬機(jī)棧會(huì)產(chǎn)生的兩種異常:

  • 如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的最大深度,會(huì)拋出StackOverFlow異常。
  • 如果虛擬機(jī)在拓展棧時(shí)無法申請(qǐng)到足夠的內(nèi)存空間,則會(huì)拋出OOM異常。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Feign如何設(shè)置超時(shí)時(shí)間(不同情況)

    Feign如何設(shè)置超時(shí)時(shí)間(不同情況)

    本文主要介紹了Feign的超時(shí)時(shí)間設(shè)置,包括單獨(dú)使用Feign和在SpringCloud環(huán)境下的設(shè)置方式,以及與Ribbon和Hystrix的配合使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • java如何多線程批量更新10萬級(jí)的數(shù)據(jù)

    java如何多線程批量更新10萬級(jí)的數(shù)據(jù)

    在處理大數(shù)據(jù)量的批量更新時(shí),直接使用mybatis的updateBatch可能導(dǎo)致效率低下甚至OOM,通過每次處理5000條數(shù)據(jù)的方式雖然安全但效率低,更優(yōu)的解決方案是使用多線程處理,將數(shù)據(jù)分批并多線程執(zhí)行,有效提高了處理速度并保證了系統(tǒng)穩(wěn)定性
    2024-10-10
  • Java加解密工具類源碼示例

    Java加解密工具類源碼示例

    最近在項(xiàng)目中接觸到了數(shù)據(jù)加解密的業(yè)務(wù),數(shù)據(jù)加密技術(shù)是網(wǎng)絡(luò)中最基本的安全技術(shù),這篇文章主要給大家介紹了關(guān)于Java加解密工具類源碼的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • 使用springboot整合mybatis-plus實(shí)現(xiàn)數(shù)據(jù)庫的增刪查改示例

    使用springboot整合mybatis-plus實(shí)現(xiàn)數(shù)據(jù)庫的增刪查改示例

    這篇文章主要介紹了使用springboot整合mybatis-plus實(shí)現(xiàn)數(shù)據(jù)庫的增刪查改示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • idea啟動(dòng)spring項(xiàng)目中文亂碼的解決方法

    idea啟動(dòng)spring項(xiàng)目中文亂碼的解決方法

    本文主要介紹了idea啟動(dòng)spring項(xiàng)目中文亂碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 使用Mybatis-Plus時(shí)的SqlSessionFactory問題及處理

    使用Mybatis-Plus時(shí)的SqlSessionFactory問題及處理

    這篇文章主要介紹了使用Mybatis-Plus時(shí)的SqlSessionFactory問題及處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • SpringCloud之@FeignClient()注解的使用詳解

    SpringCloud之@FeignClient()注解的使用詳解

    @FeignClient是SpringCloud中用于聲明一個(gè)Feign客戶端的注解,用于解決模塊方法互相調(diào)用的問題,Feign是一個(gè)聲明式的WebService客戶端,通過Feign,只需要?jiǎng)?chuàng)建一個(gè)接口,并使用注解來描述請(qǐng)求,就可以直接執(zhí)行HTTP請(qǐng)求了
    2024-11-11
  • Java編程ssh整合常見錯(cuò)誤解析

    Java編程ssh整合常見錯(cuò)誤解析

    這篇文章主要介紹了Java編程ssh整合常見錯(cuò)誤解析,如果有什么不足之處,歡迎留言補(bǔ)充。
    2017-10-10
  • Java 使用 FFmpeg 處理視頻文件示例代碼詳解

    Java 使用 FFmpeg 處理視頻文件示例代碼詳解

    這篇文章主要介紹了Java 使用 FFmpeg 處理視頻文件示例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • java學(xué)習(xí)之理解自動(dòng)拆裝箱特性

    java學(xué)習(xí)之理解自動(dòng)拆裝箱特性

    這篇文章主要介紹java自動(dòng)拆裝箱特性以及java自動(dòng)拆裝箱的應(yīng)用,有需要的朋友可以借鑒參考下,希望可以有所幫助,祝大家早日升職加薪
    2021-09-09

最新評(píng)論

峨山| 富锦市| 河池市| 安康市| 寿宁县| 甘泉县| 卢湾区| 灯塔市| 福州市| 乌什县| 油尖旺区| 伊宁市| 太原市| 余干县| 安吉县| 平原县| 通渭县| 班玛县| 洱源县| 和田市| 桐柏县| 峨山| 万盛区| 富顺县| 湘阴县| 明溪县| 安多县| 聊城市| 贵定县| 朝阳区| 固原市| 德清县| 汝州市| 皋兰县| 卢龙县| 霍林郭勒市| 鄂伦春自治旗| 朝阳区| 新巴尔虎右旗| 凤庆县| 平陆县|