JVM 系列:JVM 內存結構深度解析

你點贊了嗎?你關注了嗎?每天分享干貨好文。

高并發解決方案與架構設計。

海量數據存儲和性能優化。

通用框架/組件設計與封裝。

如何設計合適的技術架構?

如何成功轉型架構設計與技術管理?

在競爭激烈的大環境下,只有不斷提升核心競爭力才能立于不敗之地。

留言【我要晉級】,一對一指導,帶你晉級。

一、JVM 內存結構總覽

JVM 內存結構是 Java 程序運行的基石,定義了數據在虛擬機中的存儲與訪問規則。其核心分為??線程私有區域(線程隔離)??和??線程共享區域?,具體劃分如下圖

線程私有區域(線程隔離)? :程序計數器、虛擬機棧、本地方法棧

線程共享區域?:堆、方法區

從類型上分,也可以大致分為:堆、棧。堆是存儲單元,主要作用是存儲數據的。棧是運行單元,主要作用是解決程序如何運行。一個為線程執行服務,一個為全局數據存儲。

二、程序計數器(Program Counter Register)

程序計數器是線程私有的內存區域,用于存儲當前線程執行的字節碼指令地址。如果線程正在執行本地方法,程序計數器的值為空(Undefined)。

程序計數器是一塊較小的內存空間,也是運行速度最快的存儲區域。它可以看作是當前線程所執行的字節碼的行號指示器。在虛擬機的概念模型里(僅是概念模型,各種虛擬機可能會通過一些更高效的方式去實現),字節碼碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成

說人話就是:用于存儲當前線程執行的字節碼指令地址。

由于 Java 虛擬機的多線程是通過線程輪流切換并分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器(對于多核處理器來說就是一個內核)都只會執行一條線程中的指令。因此,為了線程切換后能恢復到正確的執行位置,每條線程都需要一個獨立的程序計數器,各條線程之間計數器互不影響,獨立存儲,我們稱這類的內存區域為“線程私有”的內存。

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

此內存區域是唯一一個在Java虛擬機規范中沒有任何 OutOfMemoryError 情況的區域。

生命周期:程序計數器的生命周期與線程的生命周期一致。

三、虛擬機棧(VM Stack)

虛擬機棧是線程私有的內存區域,由多個棧幀(Stack Frame)構成,在當前線程中,每調用一個方法,都會有一個對應的棧幀進行入棧,用于存儲方法調用的局部變量、操作數棧、動態鏈接、方法出口等信息。當方法結束時,對應的方法的棧幀就會進行出棧。每個線程在創建時都會分配一個棧。

虛擬機棧包含以下幾個部分:

局部變量表:用于存儲方法參數和局部變量。

操作數棧:用于存儲方法執行過程中的操作數。

動態鏈接:指向運行時常量池中該方法的引用。

方法出口:記錄方法返回的地址。

一些附加信息

生命周期:棧的生命周期與線程的生命周期一致。線程啟動時創建棧,線程結束時銷毀棧。

設置大小:Java 虛擬機規范允許 虛擬機棧的大小是動態的或者是固定的。可以通過參數-Xss來設置線程的最大棧空間,棧的大小直接決定了函數調用的最大可達深度。

當棧達到最大棧空間限制時,又要進行新的方法調用(入棧操作)時,就會拋出 StackOverflowError 異常。

當線程創建的時候,沒有足夠的空間穿件對應的虛擬機棧時,就會拋出 OutOfMemoryError 異常。

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

本地方法棧與棧類似,但它是為本地方法(Native Method)服務的。本地方法是用其他語言(如 C、C++)編寫的方法。

生命周期:本地方法棧的生命周期與線程的生命周期一致。

常見問題也與虛擬機棧類似。

五、堆(Heap)

堆是 JVM 中最大的一塊內存區域,是存儲 Java 程序中絕大多數的對象實例。是所有線程共享堆內存。Java 虛擬機規范中,把堆進行了劃分,主要分為:新生代、老年代、元空間(JDK 8 之前是永久代)。

生命周期:堆的生命周期與 JVM 的生命周期一致。JVM 啟動時創建堆,JVM 關閉時銷毀堆。

設置大小:堆的大小可以通過-Xmx(最大堆)、-Xms(初始堆)控制大小。

新生代(Young Generation)

新創建的對象一般首先分配在新生代中,除非對象過大直接進入老年代。新生代又分為 Eden 區和兩個 Survivor 區(通常稱為 S0 和 S1)。默認占比是 8 : 1 : 1。正常情況下兩個 Survivor 區總有一個是空的。后面聊垃圾回收的時候,我們可以細聊。

當 Eden 區滿了,會執行 ?Minor GC?,將 Eden 區和當前使用的 Survivor 區的幸存對象移動到空的 Survivor 區中。每經歷過一次 ?Minor GC?,幸存的對象其年齡計數器 +1,達到閾值(默認15)后會晉升至老年代。

老年代(Old Generation)

老年代通過是內存滿時執行垃圾回收,如果回收后依舊沒有空出空間,新對象無位置存儲,則會拋出 OutOfMemoryError 異常。

元空間(Metaspace)

存儲類信息、常量池等。

元空間可以通過-XX:MetaspaceSize(初始大小)、-XX:MaxMetaspaceSize(最大限制)?控制大小。

不論是 JDK 8 之前的永久代,還是 JDK 8 之后的元空間,其實都可以理解為虛擬機規范中方法區的具體實現。

雖然虛擬機規范把方法區描述為堆的一部分,但是它其實有一個別名 Non-Heap(非堆)。具體的我們詳見方法區部分。

六、方法區(Method Area)

方法區是虛擬機規范中定義的一個概念,是所有線程共享的內存區域,主要用于存儲類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。然后虛擬機規范中并沒有規定如何去實現它,不同的虛擬機廠商有不同的實現。

永久代(PermGen)則是 Hotspot 虛擬機特有的一個概念,在 JDK 8 中,又被改為元空間。

其實永久代合元空間都可以理解為是方法區的具體實現。

生命周期:方法區的生命周期與 JVM 的生命周期一致。當 JVM 啟動時,方法區被創建;當 JVM 關閉時,方法區被銷毀。

方法區主要包含以下幾個部分:

類信息:包括類的名稱、訪問修飾符、字段描述、方法描述等。

運行時常量池:用于存儲編譯期生成的各種字面量和符號引用。

靜態變量:類級別的靜態變量。

即時編譯器編譯后的代碼:JIT(Just-In-Time)編譯器將熱點代碼編譯為本地機器代碼后存儲在此。

設置大小:JDK 8 之后,可以使用參數 -XX:MetaspaceSize-XX:MaxMetaspaceSize 指定。

方法區的大小決定了JVM 可以加載多少個 Class,如果加載的 Class 過多,則會拋出 OutOfMemoryError異常。如果不指定大小的情況下,默認虛擬機會耗盡系統所有的可用內存。

-XX:MetaspaceSize :設置初始的元空間大小。64 位 JVM默認的 -XX:MetaspaceSize=2075MB,這是初始大小,當達到這個大小后,將會觸發 Full GC(Stop the world),卸載無用的 Class(Class 對應的ClassLoader 不再存活),并重置元空間大小(不超過 -XX:MaxMetaspaceSize),重置的值取決于 Full GC 后釋放了多少的元空間。

如果初始化-XX:MetaspaceSize過低,元空間的大小會發生多次調整,為了避免因為元空間初始大小過小導致的頻繁 Full GC,建議將 -XX:MetaspaceSize 設置為一個相對較高的值。

架構設計之道在于在不同的場景采用合適的架構設計,架構設計沒有完美,只有合適。

在代碼的路上,我們一起砥礪前行。用代碼改變世界!

如果有其它問題,歡迎評論區溝通。

感謝觀看,如果覺得對您有用,還請動動您那發財的手指頭,點贊、轉發、在看、收藏。

高并發解決方案與架構設計。

海量數據存儲和性能優化。

通用框架/組件設計與封裝。

如何設計合適的技術架構?

如何成功轉型架構設計與技術管理?

在競爭激烈的大環境下,只有不斷提升核心競爭力才能立于不敗之地。

留言【我要晉級】,一對一指導,帶你晉級。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/77448.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77448.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77448.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

手機上的APN是什么,該怎么設置

網上說改個APN就可以讓網速快幾倍,那到底APN是個什么東西,真的能讓網速快幾倍嗎? APN的作用 網絡連接基礎:APN(接入點名稱)是手機連接移動網絡的“橋梁”,負責識別運營商網絡類型(…

微服務治理與可觀測性

服務注冊與發現 核心功能 服務實例動態變化:實例可能因擴縮容、故障或遷移導致IP變動。服務依賴解耦:調用方無需硬編碼服務地址,降低耦合度。負載均衡:自動選擇健康實例,提升系統可用性。 核心組件 服務注冊中心&am…

嵌入式linux系統中內存管理的方法與實現

第一:linux內核管理詳解圖形 第二:Linux內存管理詳細分析 深入剖析Linux內核內存管理 作為嵌入式系統開發者,理解Linux內核的內存管理對于開發高效、穩定的系統至關重要。在這篇文章中,我們將詳細解析Linux內核如何劃分物理內存和虛擬內存,頁表、MMU(內存管理單元)與TL…

【dataframe顯示不全問題】打開一個行列超多的excel轉成df之后行列顯示不全

出現問題如下圖: 解決方案~ display.width解決列顯示不全 pd.set_option(display.max_columns,1000) pd.set_option(display.width, 1000) pd.set_option(display.max_colwidth,1000) pd.set_option(display.max_rows,1000)

Linux——Shell編程之正則表達式與文本處理器(筆記)

目錄 基礎正則表達式 1:基礎正則表達式示例 (4)查找任意一個字符“.”與重新字符“*” (5)查找連續字符范圍“{ }” 文本處理器 一、sed工具 二、awk工具 (1)按行輸出文本 (2&#xff0…

OpenHarmony系統-源碼下載,環境搭建,編譯,燒錄,調試

獲取源碼 以OpenHarmony5.0.3為例 repo init -u https://gitee.com/openharmony/manifest -b OpenHarmony-5.0.3-Release --no-repo-verify repo sync -c repo forall -c git lfs pull搭建環境 安裝必要的工具和命令 apt-get install -y apt-utils binutils bison flex bc …

Vue3 本地打包啟動白屏解決思路!! !

“為什么我訪問 http://127.0.0.1:5501/index.html 白屏,刪了 index.html 再訪問 / 就又活過來了?” —— 你的項目與 SPA 路由的“宮斗大戲” 一、問題復現 場景 本地通過 VSCode Live Server(或其他靜態服務器)啟動了打包后的 V…

數字人(2):數字人技術全景透視(2025演進版)

隨著人工智能技術的迅猛發展,數字人技術發展也是一日千里。站在當下,著眼未來,我們一起在回眸透視過去的基礎上,一起共同眺望數字人技術的未來。 一、數字人技術體系重構 我們可以用三維定義對數字人技術進行框架重構 維度 技術內涵 典型特征 物理層 人體數字化建模技術 …

小剛說C語言刷題——1035 判斷成績等級

1.題目描述 輸入某學生成績,如果 86分以上(包括 86分)則輸出 VERY GOOD ,如果在 60到 85之間的則輸出 GOOD (包括 60和 85),小于 60 的則輸出 BAD。 輸入 輸入只有一行,包括 1個整數。 輸出 輸出只有一行&#xf…

React-在使用map循環數組渲染列表時須指定唯一且穩定值的key

在渲染列表的時候,我們須給組件或者元素分配一個唯一值的key, key是一個特殊的屬性,不會最終加在元素上面,也無法通過props.key來獲取,僅在react內部使用。react中的key本質是服務于diff算法, 它的默認值是null, 在diff算法過程中…

Zookeeper的通知機制是什么?

大家好,我是鋒哥。今天分享關于【Zookeeper的通知機制是什么?】面試題。希望對大家有幫助; Zookeeper的通知機制是什么? 1000道 互聯網大廠Java工程師 精選面試題-Java資源分享網 Zookeeper 的通知機制是其核心特性之一&#xf…

【LangChain實戰】構建下一代智能問答系統:從RAG架構到生產級優化

打破傳統問答系統的次元壁 當ChatGPT在2022年掀起AI革命時,開發者們很快發現一個殘酷現實:通用大模型在專業領域的表現如同拿著地圖的盲人,既無法理解企業私有數據,也無法保證事實準確性。這催生了RAG(檢索增強生成&a…

UDS中功能尋址可以請求多幀數據嘛?當ECU響應首幀后,診斷儀是通過物理尋址發送流控幀嘛?

文章目錄 1. 前言??1.1 功能尋址是否支持請求多幀數據?1.2 ECU發送首幀(FF)后,診斷儀如何發送流控幀(FC)?1.3 協議依據(ISO 14229-1)1.4 實際應用注意事項總結1. 前言?? 在UDS(Unified Diagnostic Services)協議中,功能尋址與物理尋址的使用規則以及多幀數據傳…

PHP異常處理__Throwable

在 PHP 里,Throwable 是一個極為關鍵的接口,自 PHP 7 起被引入。它為錯誤和異常處理構建了一個統一的框架。下面會詳細介紹 Throwable 的相關內容。 1. 基本概念 Throwable 是 Exception 和 Error 的父接口。在 PHP 7 之前,異常&#xff08…

無需訓練的具身導航探索!TRAVEL:零樣本視覺語言導航中的檢索與對齊

作者: Navid Rajabi, Jana Kosecka 單位:喬治梅森大學計算機科學系 論文標題:TRAVEL: Training-Free Retrieval and Alignment for Vision-and-Language Navigation 論文鏈接:https://arxiv.org/pdf/2502.07306 主要貢獻 提出…

Vue3+Vite+TypeScript+Element Plus開發-22.客制Table組件

系列文檔目錄 Vue3ViteTypeScript安裝 Element Plus安裝與配置 主頁設計與router配置 靜態菜單設計 Pinia引入 Header響應式菜單縮展 Mockjs引用與Axios封裝 登錄設計 登錄成功跳轉主頁 多用戶動態加載菜單 Pinia持久化 動態路由 -動態增加路由 動態路由-動態刪除…

Java讀取JSON文件并將其中元素轉為JSON對象輸出

🤟致敬讀者 🟩感謝閱讀🟦笑口常開🟪生日快樂?早點睡覺 📘博主相關 🟧博主信息🟨博客首頁🟫專欄推薦🟥活動信息 文章目錄 Java讀取JSON文件并將其中元素轉為JSON對象輸…

Spring Boot自動配置原理深度解析:從條件注解到spring.factories

大家好!今天我們來深入探討Spring Boot最神奇的特性之一——自動配置(Auto-configuration)。這個功能讓Spring Boot如此受歡迎,因為它大大簡化了我們的開發工作。讓我們一起來揭開它的神秘面紗吧!👀 🌟 什么是自動配置…

【ELF2學習板】利用OpenMP采用多核并行技術提升FFTW的性能

目錄 引言 OpenMP簡介 編譯OpenMP支持的FFTW庫 部署與測試 測試程序 程序部署 測試結果 結語 引言 在前面已經介紹了在ELF2開發板上運行FFTW計算FFT。今天嘗試利用RK3588的多核運算能力來加速FFT運算。FFTW利用多核能力可以考慮使用多線程或者OpenMP。今天介紹一下Ope…

2000-2017年各省城市天然氣供氣總量數據

2000-2017年各省城市天然氣供氣總量數據 1、時間:2000-2017年 2、來源:國家統計局、能源年鑒 3、指標:行政區劃代碼、城市、年份、城市天然氣供氣總量 4、范圍:31省 5、指標說明:城市天然氣供氣總量是指在一定時間…