Java虛擬機 - 程序計數器和虛擬機棧

運行時數據結構

  • Java運行時數據區
    • 程序計數器
    • 為什么需要程序計數器
    • 執行流程
    • 虛擬機棧
      • 虛擬機棧作用
      • 虛擬機棧核心結構
      • 運行機制

Java運行時數據區

首先介紹Java運行時數據之前,我們要了解,對于計算機來說,內存是非常重要的資源,因為內存是連接CPU與硬盤的橋梁,承載著操作系統與應用程序的運行的基礎。JVM在運行期間把它管理的內存分為若干個區域,有些區域是線程私有的,有些區域是共享的。
Java運行時數據區作為JVM在程序執行過程中管理內存的核心結構,主要包括方法區(存儲類元數據、運行時常量池、靜態變量)、堆(存放對象實例和數組,被所有線程共享且是垃圾回收的主區域)、虛擬機棧(每個線程私有,用于存儲方法調用的棧幀,包含局部變量表、操作數棧及方法出口)、本地方法棧(支持Native方法調用)和程序計數器(記錄當前線程執行的字節碼位置,確保多線程切換后能恢復執行)。其中,堆和方法區是線程共享的,而虛擬機棧、本地方法棧和程序計數器為線程私有,共同協作實現Java程序的內存分配、方法執行及多線程調度。
在這里插入圖片描述

程序計數器

程序計數器(Program Counter Register)在JVM中可以當成當前線程所執行的字節碼的行號指示器,在JVM的概念模型里面,字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,它是程序控制流的指示器。分支 、循環 、跳轉 、異常處理 、線程恢復等都是依賴這個計數器來實現的。
在這里插入圖片描述
如果程序執行的是Java方法,計數器代表的是只在執行的虛擬機字節碼的地址;如果執行的是本地方法,這個計數器的值為空(undefined)。此外,這個計數器區域是Java虛擬機規范的沒有規定任何內存溢出的地方,程序計數區既沒有內存溢出,也沒有垃圾回收。因為程序計數器是很小的一塊內存區域,幾乎可以忽略不記,同時也是運行最快的區域。

為什么需要程序計數器

因為CPU需要不停的切換各個線程,做完切換之后,需要知道接下來從哪里開始執行。通過使用程序計數器保存了接下來要執行的地址,這樣CPU切換過來之后就可以直接接著執行。

執行流程

// 示例代碼
public class Demo {public int test() {int a = 10;int b = 20;int c = a + b;String d = "abd";System.out.println(d);return d.length();}
}

通過javap -c Demo.class反編譯后:

 0 bipush 102 istore_13 bipush 205 istore_26 iload_17 iload_28 iadd9 istore_3
10 ldc #2 <abd>
12 astore 4
14 getstatic #9 <java/lang/System.out : Ljava/io/PrintStream;>
17 aload 4
19 invokevirtual #15 <java/io/PrintStream.println : (Ljava/lang/String;)V>
22 aload 4
24 invokevirtual #21 <java/lang/String.length : ()I>
27 ireturn

在這里插入圖片描述

虛擬機棧

虛擬機棧(Java Virtual Machine Stack)是JVM內存模型中與線程執行密切相關的核心區域,用于存儲方法調用的棧幀(Stack Frame)。它是線程私有的內存空間,每個線程在創建時都會分配一個獨立的虛擬機棧,其生命周期與線程一致。以下從設計目標、核心結構、運行機制到常見問題全面解析。

虛擬機棧作用

虛擬機棧的核心功能是支持Java方法的調用與執行,具體包括:

  • 方法調用鏈管理:保存方法的調用順序(如 main() → methodA() → methodB())。

  • 局部變量存儲:存儲方法內的基本類型變量、對象引用。

  • 操作數計算:提供臨時數據存儲空間(如算術運算的中間結果)。

  • 方法返回控制:記錄方法執行完成后的返回地址。

虛擬機棧核心結構

虛擬機棧由多個棧幀(Stack Frame)構成,每個棧幀對應一個方法的調用。棧幀包含以下核心部分:

  1. 局部變量表(Local Variables Table)
    作用:存儲方法參數和方法內定義的局部變量。

     結構:以變量槽(Slot)為最小單位,每個Slot占用32位(long和double占2個Slot)。索引從0開始,依次存放this(非靜態方法)、方法參數、局部變量。示例:
    
public void demo(int a, String b) {double c = 3.14;Object d = new Object();
}
局部變量表結構:

在這里插入圖片描述

  1. 操作數棧(Operand Stack)

    作用:保存計算過程中的臨時數據(類似CPU的寄存器)。

    特點:

     深度在編譯期確定(寫入方法表的max_stack屬性)。通過iconst_1、iadd等字節碼指令操作棧頂元素。
    
int result = 1 + 2;
iconst_1  // 壓入1
iconst_2  // 壓入2
iadd      // 彈出1和2,相加后壓入3
istore_1  // 將3存儲到局部變量表索引1
  1. 動態鏈接(Dynamic Linking)
  • 作用:將符號引用(如com/example/Demo.methodA)轉換為直接引用(內存地址)。

  • 意義:支持多態特性(如接口方法、虛方法調用)。

  • 對比:

    • 靜態解析:類加載階段可確定的直接引用(如final方法)。

    • 動態鏈接:運行時才能確定(如重寫方法)。

  1. 方法返回地址(Return Address)
    作用:記錄方法正常結束或異常退出后的返回位置。
    兩種返回方式:
  • 正常返回(return指令):程序計數器恢復為調用者的下一條指令地址。

  • 異常退出:通過異常處理器表(Exception Table)確定跳轉地址。

運行機制

  1. 方法調用與棧幀壓棧
    調用方法時:創建新棧幀并壓入棧頂。

方法返回時:棧幀彈出,釋放內存。

  1. 棧溢出(StackOverflowError)
    觸發條件:線程請求的棧深度超過JVM允許的最大值(如無限遞歸)。

示例:

public class StackOverflowDemo {public static void main(String[] args) {infiniteCall(); // 無限遞歸調用}static void infiniteCall() {infiniteCall();}
}

報錯信息:

Exception in thread "main" java.lang.StackOverflowError
  1. 棧大小配置
    參數:-Xss(如-Xss1m設置棧大小為1MB)。

默認值:不同JVM實現不同(HotSpot Linux x64默認1MB)。

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

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

相關文章

MySQL數據庫——支持遠程IP訪問的設置方法總結

【系列專欄】&#xff1a;博主結合工作實踐輸出的&#xff0c;解決實際問題的專欄&#xff0c;朋友們看過來&#xff01; 《項目案例分享》 《極客DIY開源分享》 《嵌入式通用開發實戰》 《C語言開發基礎總結》 《從0到1學習嵌入式Linux開發》 《QT開發實戰》 《Android開發實…

CSS- 4.6 radiu、shadow、animation動畫

本系列可作為前端學習系列的筆記&#xff0c;代碼的運行環境是在HBuilder中&#xff0c;小編會將代碼復制下來&#xff0c;大家復制下來就可以練習了&#xff0c;方便大家學習。 HTML系列文章 已經收錄在前端專欄&#xff0c;有需要的寶寶們可以點擊前端專欄查看&#xff01; 點…

排序算法之基礎排序:冒泡,選擇,插入排序詳解

排序算法之基礎排序&#xff1a;冒泡、選擇、插入排序詳解 前言一、冒泡排序&#xff08;Bubble Sort&#xff09;1.1 算法原理1.2 代碼實現&#xff08;Python&#xff09;1.3 性能分析 二、選擇排序&#xff08;Selection Sort&#xff09;2.1 算法原理2.2 代碼實現&#xff…

第十節第一部分:常見的API:Math、System、Runtime

Math類介紹及常用方法&#xff08;了解知道即可&#xff09; System類介紹及常用方法&#xff08;了解知道即可&#xff09; Runtime類介紹及常用方法&#xff08;了解知道即可&#xff09; 代碼&#xff1a; 代碼一&#xff1a;Math類 package com.itheima.d14_math;public …

智能體間協作的“巴別塔困境“如何破解?解讀Agent通信4大協議:MCP/ACP/A2A/ANP

AI 智能體的興起觸發了AI應用協作的新領域。這些智能體不再局限于被動的聊天機器人或獨立的系統&#xff0c;它們現在被設計用于推理、計劃和協作ーー跨任務、跨域甚至跨組織。但隨著這一愿景成為現實&#xff0c;一個挑戰很快浮出水面&#xff1a; 智能體如何以一種安全、可伸…

項目進度延誤,如何按時交付?

項目進度延誤可以通過加強計劃管理、優化資源分配、強化團隊溝通、設置關鍵里程碑和風險管理機制等方式來實現按時交付。加強計劃管理、優化資源分配、強化團隊溝通、設置關鍵里程碑、風險管理機制。其中&#xff0c;加強計劃管理尤為關鍵&#xff0c;因為明確而詳細的計劃能提…

詳解ip地址、子網掩碼、網關、廣播地址

1. IP 地址 定義&#xff1a;IP 地址是網絡設備在網絡中的唯一標識&#xff0c;用于標識設備的網絡位置&#xff0c;類似于現實中的門牌號。它分為 IPv4&#xff08;如 192.168.1.5&#xff09;和 IPv6&#xff08;如 240e:305:3685:8100:a00:27ff:fefb:56b8&#xff09;。 示…

為 Windows 和 Ubuntu 中設定代理服務器的詳細方法

有時下載大模型總是下載不出來&#xff0c;要配置代理才行 一、Windows代理設置 ① 系統全局代理設置 打開【設置】→【網絡和Internet】→【代理】。 在【手動設置代理】下&#xff0c;打開開關&#xff0c;輸入&#xff1a; 地址&#xff1a;10.10.10.215 端口&#xff1a;…

鴻蒙OSUniApp 實現的表單驗證與提交功能#三方框架 #Uniapp

UniApp 實現的表單驗證與提交功能 前言 在移動端應用開發中&#xff0c;表單是用戶與應用交互的重要媒介。一個好的表單不僅布局合理、使用方便&#xff0c;還應該具備完善的驗證與提交功能&#xff0c;以確保用戶輸入的數據準確無誤。本文將分享如何在 UniApp 中實現表單驗證…

前端的面試筆記——HTMLJavaScript篇(二)前端頁面性能檢測

前端頁面性能檢測和判定是優化用戶體驗的核心環節&#xff0c;需要結合實驗室數據&#xff08;Lab Data&#xff09;、現場數據&#xff08;Field Data&#xff09;和行業標準綜合評估。以下是主流方法、工具及判定標準的詳細解析&#xff1a; 一、性能檢測的核心維度與指標 …

再來1章linux系列-19 防火墻 iptables 雙網卡主機的內核 firewall-cmd firewalld的高級規則

學習目標&#xff1a; 實驗實驗需求實驗配置內容和分析 &#xff08;每一個設備的每一步操作&#xff09;實驗結果驗證其他 學習內容&#xff1a; 實驗實驗需求實驗配置內容和分析 &#xff08;每一個設備的每一步操作&#xff09;實驗結果驗證其他 1.實驗 2.實驗需求 圖…

LLM-Based Agent綜述及其框架學習(五)

文章目錄 摘要Abstract1. 引言2. 文本輸出3. 工具的使用3.1 理解工具3.2 學會使用工具3.3 制作自給自足的工具3.4 工具可以擴展LLM-Based Agent的行動空間3.5 總結 4. 具身動作5. 學習智能體框架5.1 CrewAI學習進度5.2 LangGraph學習進度5.3 MCP學習進度 參考總結 摘要 本文圍繞…

游戲引擎學習第298天:改進排序鍵 - 第1部分

關于向玩家展示多個房間層所需的兩種 Z 值 我們在前一天基本完成了為渲染系統引入分層 Z 值的工作&#xff0c;但還沒有完全完成所有細節。我們開始引入圖形渲染中的分層概念&#xff0c;即在 Z 軸方向上擁有多個獨立圖層&#xff0c;每個圖層內部再使用一個單獨的 Z 值來實現…

一些C++入門基礎

關鍵字 圖引自 C 關鍵詞 - cppreference.com 命名空間 命名空間解決了C沒辦法解決的各類命名沖突問題 C的標準命名空間&#xff1a;std 命名空間中可以定義變量、函數、類型&#xff1a; namespace CS {//變量char cs408[] "DS,OS,JW,JZ";int cs 408;//函數vo…

學習筆記:黑馬程序員JavaWeb開發教程(2025.4.6)

12.4 登錄校驗-JWT令牌-介紹 JWT&#xff08;JSON Web Token&#xff09; 簡潔是指JWT是一個簡單字符串&#xff0c;自包含指的是JWT令牌&#xff0c;看似是一個隨機字符串&#xff0c;但是可以根據需要&#xff0c;自定義存儲內容 Header是JSON數據格式&#xff0c;原始JSO…

香港科技大學物理學理學(科學計算與先進材料物理與技術)碩士招生宣講會——深圳大學

香港科技大學物理學理學&#xff08;科學計算與先進材料物理與技術&#xff09;碩士招生宣講會——深圳大學專場 &#x1f559;時間&#xff1a;2025年5月23日&#xff08;星期五&#xff09;14:30 &#x1f3eb;地點&#xff1a;深圳大學滄海校區致原樓1101 &#x1f9d1…

數據庫優化技巧:MySQL 重復數據查詢與刪除(僅保留一條)的性能優化策略

目錄 一、查詢重復數據 二、刪除重復數據 方法 1&#xff1a;創建臨時表&#xff0c;操作完成后再刪除臨時表&#xff08;安全可靠&#xff0c;適合大表&#xff09; 步驟 1&#xff1a;創建臨時表存儲需刪除的 ID 步驟 2&#xff1a;根據臨時表刪除數據 方法 2&#xff1a…

分布式ID生成器:原理、對比與WorkerID實戰

一、為什么需要分布式ID&#xff1f; 在微服務架構下&#xff0c;單機自增ID無法滿足跨服務唯一性需求&#xff0c;且存在&#xff1a; ? 單點瓶頸&#xff1a;數據庫自增ID依賴單表寫入 ? 全局唯一性&#xff1a;跨服務生成可能重復 ? 擴展性差&#xff1a;分庫分表后ID規…

Golang的代碼注釋規范與實踐

# Golang的代碼注釋規范與實踐 一、注釋的重要性 代碼注釋是程序員交流的橋梁 代碼注釋是程序員之間溝通交流的重要形式&#xff0c;良好的注釋能夠幫助其他開發者更快地理解代碼的意圖和實現方式。 代碼維護離不開注釋 在項目維護過程中&#xff0c;良好的注釋能夠幫助開發者回…

Qt讀取Excel文件的技術實現與最佳實踐

目錄 一、成果展示二、核心方法及原理1. QAxObject(基于COM接口)2. 第三方庫QXlsx3. ODBC數據庫驅動三、實現步驟詳解1. QAxObject讀取Excel(需安裝Excel/WPS)2. QXlsx讀取Excel(跨平臺方案)四、技術選型與對比五、應用場景與優化建議1. 高頻數據處理2. 跨平臺工具開發3.…