JVM學習專題(二)內存模型深度剖析

目錄

1.JVM結構體系

?編輯

2.跨平臺特性?

3.JVM整體結構及內存模型

1.棧內存

1、棧幀:

1.局部變量表

2.操作數棧

3.動態鏈接

4.方法出口

2、創建對象

2.程序計數器:

3.方法區

?4.堆

5.本地方法區

6.總結


1.JVM結構體系

JDKJRE JVM的包含關系:

1)JDK=JRE+ 開發工具集(例如Javac,java編譯工具等)

2) JRE=JVM+JavaSE標準類庫(java核心類庫)

3) 如果只想運行開發好的 .class文件 只需要JRE

2.跨平臺特性?

.java文件經過javac指令變成.class字節碼文件?,再通過java命令進入到java虛擬機里面運行,同樣的文件到不同環境的jvm運行都會產生不同的二進制機器碼,字節碼是統一的,但JVM生成的機器碼會因環境而異

一次編譯,到處運行

每個不同版本的JDK內部都有對應的不同操作系統的jvm環境,也就是不同版本的jvm去實現的

3.JVM整體結構及內存模型

總共是有3塊部分,運行流程也是如下:

1.類加載子系統

2.運行時數據區(內存模型)

3.字節碼執行引擎

1.棧內存

我們來看一個簡單的代碼

比如我們有一個main主方法,當我們運行的時候會有一個主線程來運行這個方法,此時java虛擬機會在線程棧內分配一塊獨立的空間,用來存放我們線程執行過程中用到的局部變量。不同的線程執行都有自己的內存空間去放局部變量,這就是棧內存。每一個方法的局部變量都有在棧內存里面的一塊棧幀內存區域來存放,每個棧幀區域都是獨立的不會嵌套,這個棧就是數據結構的那個先進后出的棧,因此代碼的從外到內執行變成了從上到下執行,符合!

上圖代碼的jvm處理字節碼文件的指令:

1、棧幀:

棧幀的內部也有很多區域,如下圖:

1.局部變量表

一開始存的就是具體方法的局部變量a之類的

??數據類型????存儲方式????示例??
??基本類型??直接存儲值(int, float, boolean等)int a = 10;
??對象引用??存儲指向堆內存對象的指針(reference)String s = "hello";

后續會被操作數棧賦值?

2.操作數棧

比如上述代碼的int a=2,常量2先通過JVM內的指令iconst_1壓入操作數棧里,局部變量表中分配的一塊內存空間給變量a,然后通過指令istore_1使常量2先出棧,再存入局部變量表使a=2賦值,注意,在JVM中字節碼指令的執行是原子性的,istore_1??原子操作??,先彈出棧頂值,再存入局部變量表,保證每條指令在執行時 ??不會被線程調度打斷。

雖然運算過程發生在??操作數棧??內,但JVM執行算術指令時,??必須先將操作數從棧頂彈出??,運算完成后再將結果壓回棧頂

3.動態鏈接

在運行時確定方法的實際調用地址?,比如動態鏈接確定實際調用的compute()方法,我們調用這個方法的時候得去知道這個方法內部有哪些指令,因為compute()已經放入常量池里面了,相當于目前只是個符號,當運行到這個符號的時候需要去解析,加載時會解析所有方法的符號引用,但??非靜態方法的綁定推遲到運行時??(因多態,將符號引用Math.compute:()存入??運行時常量池??,但??不解析具體地址??,因可能有子類覆蓋),所以compute()只能在程序運行的時候加載,程序運行的時候把符號引用轉換成對應代碼的內存直接地址(或者說是直接引用)?

4.方法出口

compute()方法執行完要出computr()方法的棧幀回到main()方法的棧幀里面

2、創建對象

?

當我們new了一個對象之后,這個math對象會存入堆里面,但是此時棧里面的main()方法的棧幀里面也有一個局部變量表里的math變量,這兩個math的關系是:

棧:本質是一個??引用??,存儲堆里math對象的地址,類似于指針

堆:包含對象頭(類型指針、GC標記等)、實例數據(字段)和方法表(vtable)等實際內容

因此我們可以得到一個結論:棧里面的很多局部變量都是指向堆里面的地址

====================================================================

2.程序計數器:

程序計數器也是在一個線程里面的,和棧內存一樣,是線程私有??的內存區域。

作用:

1.?記錄當前線程正在執行的字節碼指令的地址?

2.存儲下一條要執行的指令地址?

????????當JVM執行字節碼時,程序計數器(PC寄存器)會??指向當前線程正在執行的指令的地址??

3.控制程序執行流程?

????????順序執行??:??字節碼執行引擎??會動態修改程序計數器的值

4.線程切換后恢復執行?

????????當線程被操作系統掛起(如時間片用完),PC會保存當前執行位置。

????????線程恢復時,JVM根據程序計數器的值繼續執行??,確保程序邏輯正確。

====================================================================

3.方法區

方法區存的是常量池,所以也叫運行時常量池

方法區=常量+靜態變量+類信息

當我們new了一個靜態變量的user對象,這個對象會存入堆里面,此時user變量是存入方法區里面的,因為他是靜態變量,所以這里也是方法區里面的user變量指向堆里面的user對象

因此我們又可以得到一個結論:方法區里面的很多靜態變量都是指向堆里面的地址

拓展一下常量池類型:

  1. 類文件常量池?? (Class File Constant Pool)

    • 存儲在.class文件中
    • 包含編譯期確定的各種符號引用和字面量
  2. ??運行時常量池?? (Runtime Constant Pool)

    • 每個類/接口獨有的
    • 在類加載時從類文件常量池創建
  3. ??字符串常量池?? (String Constant Pool)

    • 專門存儲字符串字面量
    • Java 7開始從方法區移到堆內存
  4. ??基本類型包裝類常量池??

    • 如IntegerCache、LongCache等
    • 緩存特定范圍內的基本類型包裝對象
  5. ??符號引用常量池?? (Symbol Table)

    • JVM內部使用的符號表
    • 存儲類、方法、字段等的符號引用
  6. ??動態常量池?? (Dynamic Constant Pool)

    • Java 11引入
    • 支持動態語言特性
  7. ??本地方法常量池?? (Native Method Constant Pool)

    • 為本地方法調用服務的常量池
  8. ??匿名類常量池?? (Anonymous Class Constant Pool)

    • 為匿名類特化的常量池結構

====================================================================

?4.堆

結構圖:

區域分為:

堆=年輕代(Eden+s0+s1)+老年代? ? ? ? s0+s1:Survivor區?

我們new出來的對象大部分都放在Eden區

1、如果Eden放滿了怎么辦?那么字節碼執行引擎開啟垃圾收集線程(垃圾回收GC),會把無用的對象回收

所有GC Roots??共同作為起點,比如靜態變量區和方法區的對象開始找引用對象,當找到某個對象不再被GC Roots直接或間接引用,就是說沒有任何引用鏈連接到GC Roots,此時這條線上的所有節點都會被標記為非垃圾對象,因此會把這些對象從Eden復制到Survivor區s0,剩下的就是垃圾對象會被刪除。

2、當Eren第2次滿了,這時候會再次觸發上述流程(放入Eden里對象),只不過滿了之后回收的區域變成了Eren+s0,非垃圾對象會從Eren+s0區到s1區,剩下的垃圾對象再次被刪除。

3、如果第3次滿了,再次觸發上述流程,只不過回收的區域變成了Eren+s1,非垃圾對象會從Eren+s1區到s0區,剩下的垃圾對象再次被刪除。

4、每挪一次,對象的分段年齡會+1,一般達到15次會進入老年區;當放入s0或者s1的時候放不下也會直接放入老年區

注意:??靜態變量區屬于GC Roots??它本身不會被回收,而是通過它判斷堆內對象是否存活。通常會進入到老年代的有:靜態變量、對象池、緩存對象、spring容器里的對象

====================================================================

5.本地方法區

比如start()方法里面會調用一個本地方法接口是用C++寫的,通過native關鍵字聲明的方法:

本地方法會去找.dll文件

====================================================================

6.總結

當你讀完讀明白整篇文章的時候,你應該就理解如下圖片了:

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

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

相關文章

Flink之Table API

Apache Flink 的 Table API 是 Flink 提供的一種高級抽象,用于以聲明式方式處理批處理和流處理數據。它是基于關系模型的 API,用戶可以像編寫 SQL 一樣,以簡潔、類型安全的方式編寫數據處理邏輯。 一、基本概念 1. 什么是 Table API&#xf…

基于Vue3.0的高德地圖api教程005:實現繪制線并編輯功能

文章目錄 6、繪制多段線6.1 繪制多段線6.1.1 開啟繪制功能6.1.2 雙擊完成繪制6.1.3 保存到數據庫6.2 修改多段線6.2.1 點擊線,進入編輯模式6.2.2 編輯線6.3 完整代碼6、繪制多段線 6.1 繪制多段線 6.1.1 開啟繪制功能 實現代碼: const changeSwitchDrawPolyline = ()=>…

“redis 目標計算機積極拒絕,無法連接” 解決方法,每次開機啟動redis

如果遇到以上問題 先打開“服務” 找到App Readiness 右擊-啟動 以管理員身份運行cmd,跳轉到 安裝redis的目錄 運行:redis-server.exe redis.windows.conf 以管理員身份打開另一cmd窗口,跳轉到安裝redis的目錄 運行:redis-…

Java 大視界——Java 大數據在智慧交通智能停車誘導系統中的數據融合與實時更新

面對城市停車資源錯配導致的30%以上交通擁堵問題&#xff0c;本文以某新一線城市智慧交通項目為藍本&#xff0c;深度解析Java大數據技術如何實現多源停車數據融合、動態路徑規劃與誘導策略優化。通過構建“感知-計算-決策”全鏈路系統&#xff0c;實現車位狀態更新延遲<200…

牛客周賽 Round 92(再現京津冀藍橋杯???)

1. 小紅的簽到題 現在小紅希望你寫出一個長度為 nnn 的、使用了下劃線命名法命名的變量。為了顯出特征&#xff0c;請保證該變量至少由兩個單詞組成。 輸入描述: 輸入一個正整數 n(3≦n≦100)&#xff0c;代表需要構造的變量長度。 輸出描述: 輸出一個長度為 n 的字符串&#x…

2025-05-11 Unity 網絡基礎11——UnityWebRequest

文章目錄 1 UnityWebRequest 介紹2 搭建 HTTP 服務器3 常用操作3.1下載資源3.1.1 下載文本3.1.2 下載圖片3.1.3 下載 AB 包 3.2 上傳資源3.2.1 上傳數據類3.2.2 POST 上傳3.3.3 PUT 上傳 4 自定義操作4.1 下載資源4.1.1 Unity 內置 Handler4.1.2 自定義 Handler 4.2 上傳資源4.…

GitHub 趨勢日報 (2025年05月09日)

本日報由 TrendForge 系統生成 https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日整體趨勢 Top 10 排名項目名稱項目描述今日獲星總星數語言1voideditor/void? 1879? 15214TypeScript2ruanyf/weekly科技愛好者周刊&…

.NET MAUI 基礎知識

文章目錄 什么是 .NET MAUI&#xff1f;MAUI的核心特點與Xamarin.Forms的區別 開發環境搭建安裝Visual Studio 2022安裝必要組件配置Android開發環境配置iOS開發環境驗證安裝 創建第一個MAUI應用創建新項目MAUI項目結構解析理解關鍵文件運行應用程序簡單修改示例使用熱重載 MAU…

卷積神經網絡全連接層詳解:特征匯總、FCN替代與性能影響分析

【內容摘要】 本文聚焦卷積神經網絡&#xff08;CNN&#xff09;的全連接層&#xff0c;詳細介紹其將二維特征圖轉化為一維向量的過程&#xff0c;闡述全卷積網絡&#xff08;FCN&#xff09;如何通過轉置卷積替代全連接層以實現像素級分類&#xff0c;并分析全連接層對圖像分類…

在C++中進行套接字編程時,主要使用以下頭文件

目錄 一.基本套接字頭文件<sys/socket.h><netinet/in.h><arpa/inet.h><unistd.h><netdb.h> 二. 完整示例頭文件包含三. 注意事項 在C中進行套接字編程時&#xff0c;主要使用以下頭文件&#xff1a; 一.基本套接字頭文件 <sys/socket.h>…

【Linux網絡】HTTP

應用層協議 HTTP 前置知識 我們上網的所有行為都是在做IO&#xff0c;&#xff08;我的數據給別人&#xff0c;別人的數據給我&#xff09;圖片。視頻&#xff0c;音頻&#xff0c;文本等等&#xff0c;都是資源答復前需要先確認我要的資源在哪臺服務器上&#xff08;網絡IP&…

JAVA異常體系

在 Java 里&#xff0c;異常體系是其錯誤處理機制的核心內容&#xff0c;它能夠幫助開發者有效應對程序運行時出現的各種意外狀況。 異常體系的基本架構 它主要包含兩個重要分支&#xff1a; Error&#xff08;錯誤&#xff09;&#xff1a;這類異常是程序自身無法處理的嚴重…

vue 去掉右邊table的下拉條與下面的白色邊框并補充滿

::v-deep table {width: 100% !important; } ::v-deep .el-table::after, .el-table::before {display: none !important; }/* 隱藏滾動條但保留滾動功能 */ ::v-deep .el-table__body-wrapper::-webkit-scrollbar {width: 0 !important;height: 0 !important; }::v-deep .el-t…

uniapp+vue3+uview來開發我們的項目

前言&#xff1a; 就像我們vue的web的框架element、iview等一樣&#xff0c;我們的uni-app開發也有適合的他的框架&#xff0c;除了他本身的擴展組件以外&#xff0c;第三方好用的就是就是uview了。 實現效果&#xff1a; 官網信息&#xff1a; vue2版本&#xff1a;uview-ui …

數據倉庫:企業數據管理的核心引擎

一、數據倉庫的由來 數據倉庫&#xff08;Data Warehouse, DW&#xff09;概念的誕生源于企業對數據價值的深度挖掘需求。在1980年代&#xff0c;隨著OLTP&#xff08;聯機事務處理&#xff09;系統在企業中的普及&#xff0c;傳統關系型數據庫在處理海量數據分析時顯露出明顯瓶…

YOLOv12模型部署(保姆級)

一、下載YOLOv12源碼 1.通過網盤分享的文件&#xff1a;YOLOv12 鏈接: https://pan.baidu.com/s/12-DEbWx1Gu7dC-ehIIaKtQ 提取碼: sgqy &#xff08;網盤下載&#xff09; 2.進入github克隆YOLOv12源碼包 二、安裝Anaconda/pycharm 點擊獲取官網鏈接(anaconda) 點擊獲取…

一篇解決Redis:持久化機制

目錄 認識持久化 持久化方案 RDB&#xff08;Redis DataBase&#xff09; 手動觸發 自動觸發 小結 AOF(Append-Only File) AOF緩沖區刷新機制 AOF重寫機制 AOF重寫流程 ?編輯 混合持久化 認識持久化 我們都知道Mysql有四大特征&#xff0c;原子性&#xff0c;持久…

從 Vue3 回望 Vue2:事件總線的前世今生

從 Vue3 回望 Vue2&#xff1a;事件總線的前世今生 以 Vue3 開發者視角回顧 Vue2 中事件總線機制 的文章。文章將圍繞事件總線的緣起、用法、局限與演進展開&#xff0c;幫助 Vue3 開發者理解 Vue2 通信方式的歷史意義及現代替代方案。 一、前言&#xff1a;Vue3 時代&#xff…

CSS結構性偽類、UI偽類與動態偽類全解析:從文檔結構到交互狀態的精準選擇

一、結構性偽類選擇器&#xff1a;文檔樹中的位置導航器 結構性偽類選擇器是CSS中基于元素在HTML文檔樹中的層級關系、位置索引或結構特征進行匹配的一類選擇器。它們無需依賴具體的類名或ID&#xff0c;僅通過文檔結構即可精準定位元素&#xff0c;是實現響應式布局和復雜文檔…

【SSL證書系列】SSL證書工作原理解讀

SSL&#xff08;Secure Sockets Layer&#xff09;及其繼任者TLS&#xff08;Transport Layer Security&#xff09;是用于保護網絡通信安全的加密協議。SSL證書是實現HTTPS協議的核心&#xff0c;其工作原理涉及加密技術、身份驗證和信任機制。以下是其工作原理的詳細分步解析…