【JVM內存結構系列】二、線程私有區域詳解:程序計數器、虛擬機棧、本地方法棧——搞懂棧溢出與線程隔離

上一篇文章我們搭建了JVM內存結構的整體框架,知道程序計數器、虛擬機棧、本地方法棧屬于“線程私有區域”——每個線程啟動時會單獨分配內存,線程結束后內存直接釋放,無需GC參與。這三個區域看似“小眾”,卻是理解線程執行邏輯、排查棧溢出異常的關鍵,也是面試中高頻被問的考點。今天我們就深入拆解這三個區域,從“作用原理”到“異常場景”,再到“實戰配置”,徹底搞懂線程私有區域的底層邏輯。

一、程序計數器:線程的“執行路標”,為何是唯一不會OOM的區域?

在多線程環境中,CPU會在不同線程間頻繁切換——當線程A執行到一半被暫停,切換到線程B執行,等線程A再次獲得CPU時,如何知道自己該從哪行代碼繼續執行?答案就藏在“程序計數器”里。
在這里插入圖片描述

1. 程序計數器的核心作用:記錄執行位置

程序計數器(Program Counter Register)的本質是一塊“小型內存區域”,它的唯一作用是存儲當前線程正在執行的字節碼指令的地址(或行號) 。具體來說,有兩種執行場景:

  • 當線程執行Java方法時,計數器存儲的是“當前字節碼指令的偏移地址”——比如OrderService.createOrder()方法對應的字節碼文件中,第10行指令的地址;
  • 當線程執行Native方法時(如System.currentTimeMillis()),計數器的值會被設為“Undefined”——因為Native方法由C/C++實現,不屬于Java字節碼范疇,JVM無法跟蹤其執行位置。

舉個實際例子:假設線程A正在執行calculateSum(100)方法,執行到字節碼的第20行(計算累加的關鍵步驟)時,CPU被切換到線程B。此時線程A的程序計數器會“記住”第20行的地址;當線程A再次獲得CPU時,JVM會讀取程序計數器中的地址,直接跳轉到第20行繼續執行,不會出現“重復執行”或“執行中斷”的問題。

2. 為什么必須是“線程私有”?

這是新手最容易困惑的問題,答案其實和“線程切換”的特性直接相關:每個線程的執行路徑、代碼邏輯都是獨立的——線程A在執行訂單創建方法,線程B在執行支付回調方法,它們的字節碼指令地址完全不同。如果程序計數器是“線程共享”的,那么線程切換時,計數器的值會被覆蓋,導致線程恢復執行時找不到正確位置。

因此,JVM會為每個線程單獨分配一塊程序計數器內存,線程間的計數器值互不干擾——線程啟動時創建,線程結束時銷毀,全程與線程生命周期綁定,這就是“線程隔離”的底層保障之一。

3. 特殊點:唯一不會OOM的JVM內存區域

《Java虛擬機規范》明確規定:程序計數器的內存大小是“固定的”,不會隨著線程執行過程動態擴展。它的內存大小取決于當前線程執行的方法——比如執行簡單的getter方法,需要記錄的指令地址較少,計數器占用內存就小;執行復雜的循環方法,指令地址雖多,但計數器仍能通過固定大小的內存存儲(本質是地址值,占用空間有限)。

正因為內存大小固定,程序計數器永遠不會出現“內存不足”的情況,也就成為了JVM中唯一不會拋出OutOfMemoryError的內存區域。這一點在面試中經常被問到,一定要記牢。

二、虛擬機棧:方法調用的“臨時舞臺”,棧溢出的根源在這里

如果說程序計數器是“執行路標”,那虛擬機棧就是線程執行方法的“臨時舞臺”——每個方法的調用、執行、返回,都對應虛擬機棧中“棧幀”的入棧、執行、出棧過程。理解虛擬機棧,就能搞懂“遞歸為什么會棧溢出”“局部變量存在哪里”這些實際問題。
在這里插入圖片描述

1. 虛擬機棧的核心結構:棧幀的“四大部分”

虛擬機棧(Java Virtual Machine Stack)的本質是“棧式結構的內存區域”,其中存儲的基本單位是“棧幀”(Stack Frame)。每個Java方法被調用時,JVM會創建一個對應的棧幀,并入棧;當方法執行完成(正常返回或拋出異常),棧幀會出棧并釋放內存。

一個棧幀包含四大部分,我們用“調用UserService.getUserById(100)方法”為例,拆解每部分的作用:

(1)局部變量表:存儲方法的局部變量

局部變量表是棧幀中最核心的部分之一,它存儲方法的參數、局部變量,以及方法執行過程中創建的臨時變量。比如getUserById(int id)方法中,參數id(值為100)、方法內定義的User user = null變量,都會存在局部變量表中。

局部變量表的大小在“編譯期”就已確定——JVM會根據方法的參數和局部變量數量,計算出所需的“變量槽”(Slot)數量,并存入字節碼文件中。比如一個int類型的變量占1個Slot,longdouble類型占2個Slot,對象引用(如User user)也占1個Slot(存儲的是對象在堆中的地址)。<

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

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

相關文章

紅帽認證升級華為openEuler證書活動!

如果您有紅帽證書&#xff0c;可以升級以下相應的證書&#xff1a;&#x1f447; 有RHCSA證書&#xff0c;可以99元升級openEuler HCIA 有RHCE證書&#xff0c;可以99元升級openEuler HCIP 有RHCA證書&#xff0c;可以2100元升級openEuler HCIE 現金激勵&#xff1a;&#x1f4…

迭代器模式與幾個經典的C++實現

迭代器模式詳解1. 定義與意圖迭代器模式&#xff08;Iterator Pattern&#xff09; 是一種行為設計模式&#xff0c;它提供一種方法順序訪問一個聚合對象中的各個元素&#xff0c;而又不暴露該對象的內部表示。主要意圖&#xff1a;為不同的聚合結構提供統一的遍歷接口。將遍歷…

epoll 陷阱:隧道中的高級負擔

上周提到了 tun/tap 轉發框架的數據通道結構和優化 tun/tap 轉發性能優化&#xff0c;涉及 RingBuffer&#xff0c;packetization 等核心話題。我也給出了一定的數據結構以及處理邏輯&#xff0c;但竟然沒有高尚的 epoll&#xff0c;本文說說它&#xff0c;因為它不適合。 epo…

微前端架構常見框架

1. iframe 這里指的是每個微應用獨立開發部署,通過 iframe 的方式將這些應用嵌入到父應用系統中,幾乎所有微前端的框架最開始都考慮過 iframe,但最后都放棄,或者使用部分功能,原因主要有: url 不同步。瀏覽器刷新 iframe url 狀態丟失、后退前進按鈕無法使用。 UI 不同…

SQL Server更改日志模式:操作指南與最佳實踐!

全文目錄&#xff1a;開篇語**前言****摘要****概述&#xff1a;SQL Server 的日志模式****日志模式的作用****三種日志模式**1. **簡單恢復模式&#xff08;Simple&#xff09;**2. **完整恢復模式&#xff08;Full&#xff09;**3. **大容量日志恢復模式&#xff08;Bulk-Log…

git的工作使用中實際經驗

老輸入煩人的密碼 每次我git pull的時候都要叫我輸入三次煩人的密碼&#xff0c;問了deepseek也沒有嘗試成功 出現 enter passphrase for key ‘~/.ssh/id_rsa’ 的原因: 在生成key的時候,沒有注意,不小心設置了密碼, 導致每次提交的時候都會提示要輸入密碼, 也就是上面的提示…

科技賦能,寧夏農業繪就塞上新“豐”景

在賀蘭山的巍峨身影下&#xff0c;在黃河水的溫柔滋養中&#xff0c;寧夏這片古老而神奇的土地&#xff0c;正借助農業科技的磅礴力量&#xff0c;實現從傳統農耕到智慧農業的華麗轉身&#xff0c;奏響一曲科技與自然和諧共生的壯麗樂章。一、數字農業&#xff1a;開啟智慧種植…

imx6ull-驅動開發篇36——Linux 自帶的 LED 燈驅動實驗

在之前的文章里&#xff0c;我們掌握了無設備樹和有設備樹這兩種 platform 驅動的開發方式。但實際上有現成的&#xff0c;Linux 內核的 LED 燈驅動采用 platform 框架&#xff0c;我們只需要按照要求在設備樹文件中添加相應的 LED 節點即可。本講內容&#xff0c;我們就來學習…

深度學習中主流激活函數的數學原理與PyTorch實現綜述

1. 定義與作用什么是激活函數&#xff1f;激活函數有什么用&#xff1f;答&#xff1a;激活函數&#xff08;Activation Function&#xff09;是一種添加到人工神經網絡中的函數&#xff0c;旨在幫助網絡學習數據中的復雜模式。類似于人類大腦中基于神經元的模型&#xff0c;激…

Linux高效備份:rsync + inotify實時同步

一、rsync 簡介 rsync&#xff08;Remote Sync&#xff09;是 Linux 系統下的數據鏡像備份工具&#xff0c;支持本地復制、遠程同步&#xff08;通過 SSH 或 rsync 協議&#xff09;&#xff0c;是一個快速、安全、高效的增量備份工具。二、rsync 特性 支持鏡像保存整個目錄樹和…

一種通過模板輸出Docx的方法

起因在2個群里都有網友討論這個問題&#xff0c;俺就寫了一個最簡單的例子。其實&#xff0c;我們經常遇到一些Docx的輸出的需求&#xff0c;“用模板文件進行處理”是最簡單的一個方法&#xff0c;如果想預覽也簡單 DevExpress 、Teleric 都可以&#xff0c;而且也支持 Web 、…

探索 List 的奧秘:自己動手寫一個 STL List?

&#x1f4d6;引言大家好&#xff01;今天我們要一起來揭開 C 中 list 容器的神秘面紗——不是直接用 STL&#xff0c;而是親手實現一個簡化版的 list&#xff01;&#x1f389;你是不是曾經好奇過&#xff1a;list 是怎么做到高效插入和刪除的&#xff1f;&#x1f50d;迭代器…

mysql占用高內存排查與解決

mysql占用高內存排查-- 查看當前全局內存使用情況&#xff08;需要啟用 performance_schema&#xff09; SELECT * FROM sys.memory_global_total; -- 查看總內存使用 SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10; -- 按模塊分類查看內存使用排行memory/perfor…

構建真正自動化知識工作的AI代理

引言&#xff1a;新一代生產力范式的黎明 自動化知識工作的人工智能代理&#xff08;AI Agent&#xff09;&#xff0c;或稱“智能體”&#xff0c;正迅速從理論構想演變為重塑各行各業生產力的核心引擎。這些AI代理被定義為能夠感知環境、進行自主決策、動態規劃、調用工具并持…

青少年機器人技術(四級)等級考試試卷-實操題(2021年12月)

更多內容和歷年真題請查看網站&#xff1a;【試卷中心 -----> 電子學會 ----> 機器人技術 ----> 四級】 網站鏈接 青少年軟件編程歷年真題模擬題實時更新 青少年機器人技術&#xff08;四級&#xff09;等級考試試卷-實操題&#xff08;2021年12月&#xff09; …

最新短網址源碼,防封。支持直連、跳轉。 會員無廣

最新短網址源碼&#xff0c;防封。支持直連、跳轉。 會員無廣告1.可將長網址自動縮短為短網址&#xff0c;方便記憶和使用。2.短網址默認為臨時有效&#xff0c;可付費升級為永久有效&#xff0c;接入支付后可自動完成&#xff0c;無需人工操作。3.系統支持設置圖片/文字/跳轉頁…

緩存-變更事件捕捉、更新策略、本地緩存和熱key問題

緩存-基礎知識 熟悉計算機基礎的同學們都知道&#xff0c;服務的存儲大多是多層級的&#xff0c;呈現金字塔類型。通常來說本機存儲比通過網絡通信的外部存儲更快&#xff08;現在也不一定了&#xff0c;因為網絡傳輸速度很快&#xff0c;至少可以比一些過時的本地存儲設備速度…

報表工具DevExpress .NET Reports v25.1新版本亮點:AI驅動的擴展

DevExpress Reporting是.NET Framework下功能完善的報表平臺&#xff0c;它附帶了易于使用的Visual Studio報表設計器和豐富的報表控件集&#xff0c;包括數據透視表、圖表&#xff0c;因此您可以構建無與倫比、信息清晰的報表。 DevExpress Reporting控件日前正式發布了v25.1…

kubernetes中pod的管理及優化

目錄 2 資源管理方式 2.1 命令式對象管理 2.2 資源類型 2.2.1 常用的資源類型 2.2.2 kubectl常見命令操作 2.3 基本命令示例 2.4 運行和調試命令示例 2.5 高級命令示例 3 pod簡介 3.1 創建自主式pod&#xff08;生產環境不推薦&#xff09; 3.1.1 優缺點 3.1.2 創建…

解釋一下,Linux,shell,Vmware,Ubuntu,以及Linux命令和shell命令的區別

Linux 操作系統概述Linux 是一種開源的類 Unix 操作系統內核&#xff0c;由 Linus Torvalds 于 1991 年首次發布。作為現代計算的基礎設施之一&#xff0c;它具有以下核心特征&#xff1a;多用戶多任務特性允許多個用戶同時操作系統資源&#xff0c;而模塊化設計使其能夠適應從…