細說虛擬機棧

来源:http://www.cnblogs.com/Codenewbie/archive/2016/12/15/6184898.html
-Advertisement-
Play Games

文章出自 http://www.mynawang.com/ 引文 對JVM不瞭解的請先訪問文章《Java虛擬機運行時數據區》,相信會讓你大致瞭解各個記憶體區域的對應功能。接著,我們開始細說虛擬機棧 前文中說到:“虛擬機棧是線程私有的,每創建一個線程,虛擬機就會為這個線程創建一個虛擬機棧,虛擬機棧表示J ...


文章出自 

http://www.mynawang.com/

 

引文

    對JVM不瞭解的請先訪問文章《Java虛擬機運行時數據區》,相信會讓你大致瞭解各個記憶體區域的對應功能。接著,我們開始細說虛擬機棧     前文中說到:“虛擬機棧是線程私有的,每創建一個線程,虛擬機就會為這個線程創建一個虛擬機棧,虛擬機棧表示Java方法執行的記憶體模型,每調用一個方法就會為每個方法生成一個棧幀(Stack Frame),用來存儲局部變數表、操作數棧、動態鏈接、方法出口等信息。每個方法被調用和完成的過程,都對應一個棧幀從虛擬機棧上入棧和出棧的過程。虛擬機棧的生命周期和線程是相同的”。

虛擬機棧

    其中,虛擬機棧是一個後入先出的棧。棧幀是保存在虛擬機棧中的,棧幀是用來存儲數據和存儲部分過程結果的數據結構,同時也被用來處理動態鏈接(Dynamic Linking)、方法返回值和異常分派(Dispatch Exception)。線程運行過程中,只有一個棧幀是處於活躍狀態,稱為“當前活躍棧幀”,當前活動棧幀始終是虛擬機棧的棧頂元素。如下圖所示: 棧流程

棧幀

    上述內容已對棧幀做了大致介紹,接下去仔細描述棧幀中的操作數棧,動態連接,方法返回地址和一些額外的附加信息。 如下圖所示:

棧幀詳情

1.局部變數表

    局部變數表是一組局部變數值存儲空間,用於存放方法參數和方法內部定義的局部變數。在Java文件編譯為Class文件時,就在方法表的Code屬性的max_locals數據項中確定了該方法需要分配的最大局部變數表的容量。

2.操作數棧

    操作數棧也常被稱為操作棧,它是一個後入先出棧。JVM底層位元組碼指令集是基於棧類型的,所有的操作碼都是對操作數棧上的數據進行操作,對於每一個方法的調用,JVM會建立一個操作數棧,以供計算使用。和局部變數一樣。操作數棧的最大深度也是編譯的時候寫入到方法表的code屬性的max_stacks數據項中。操作數棧的每一個元素可以是任意的Java數據類型,包括long、double。32位數據類型所占的棧容量為1,64位數據類型所占的棧容量為2。棧容量的單位為“字寬”,對於32位虛擬機來說,一個“字寬”占4個位元組,64位虛擬機來說,一個“字寬”占8個位元組。當一個方法剛剛執行的時候,這個方法的操作數棧是空的,在方法執行的過程中,會有各種位元組碼指向操作數棧中寫入和提取值,也就是入棧與出棧操作。例如,在做算術運算的時候就是通過操作數棧來進行的,又或者調用其它方法的時候是通過操作數棧來行參數傳遞的。 另外,在概念模型中,兩個棧幀作為虛擬機棧的元素,相互之間是完全獨立的,但是大多數虛擬機的實現里都會作一些優化處理,令兩個棧幀出現一部分重疊。讓下棧幀的部分操作數棧與上面棧幀的部分局部變數表重疊在一起,這樣在進行方法調用返回時就可以共用一部分數據,而無須進行額外的參數複製傳遞了。

3.動態連接

    每個棧幀都包含一個指向運行時常量池中該棧幀所屬性方法的引用,持有這個引用是為了支持方法調用過程中的動態連接。在Class文件的常量池中存有大量的符號引用,位元組碼中的方法調用指令就以常量池中指向方法的符號引用為參數。這些符號引用一部分會在類載入階段或第一次使用的時候轉化為直接引用,這種轉化稱為靜態解析。另外一部分將在每一次的運行期期間轉化為直接引用,這部分稱為動態連接

4.方法返回地址

    當一個方法被執行後,有兩種方式退出這個方法。第一種方式是執行引擎遇到任意一個方法返回的位元組碼指令,這時候可能會有返回值傳遞給上層的方法調用者(調用當前方法的的方法稱為調用者),是否有返回值和返回值的類型將根據遇到何種方法返回指令來決定,這種退出方法方式稱為正常完成出口(Normal Method Invocation Completion)。另外一種退出方式是,在方法執行過程中遇到了異常,並且這個異常沒有在方法體內得到處理,無論是Java虛擬機內部產生的異常,還是代碼中使用athrow位元組碼指令產生的異常,只要在本方法的異常表中沒有搜索到匹配的異常處理器,就會導致方法退出,這種退出方式稱為異常完成出口(Abrupt Method Invocation Completion)。一個方法使用異常完成出口的方式退出,是不會給它的調用都產生任何返回值的。     無論採用何種方式退出,在方法退出之前,都需要返回到方法被調用的位置,程式才能繼續執行,方法返回時可能需要在棧幀中保存一些信息,用來幫助恢復它的上層方法的執行狀態。一般來說,方法正常退出時,調用者PC計數器的值就可以作為返回地址,棧幀中很可能會保存這個計數器值。而方法異常退出時,返回地址是要通過異常處理器來確定的,棧幀中一般不會保存這部分信息。 方法退出的過程實際上等同於把當前棧幀出棧,因此退出時可能執行的操作有:恢覆上層方法的局部變數表和操作數棧,把返回值(如果有的話)壓入調用都棧幀的操作數棧中,調用PC計數器的值以指向方法調用指令後面的一條指令等。

5.附加信息

    虛擬機規範允許具體的虛擬機實現增加一些規範里沒有描述的信息到棧幀中,例如與高度相關的信息,這部分信息完全取決於具體的虛擬機實現。在實際開發中,一般會把動態連接,方法返回地址與其它附加信息全部歸為一類,稱為棧幀信息。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今日問題: 請問主程式輸出結果是什麼?(點擊以下“【Java每日一題】20161216”查看20161215問題解析) 題目原發佈於公眾號、簡書:【Java每日一題】20161216,【Java每日一題】20161216 註:weknow團隊近期開通並認證了分答,歡迎大家收聽,有問題也歡迎到分答來咨 ...
  • 本文面向php語言的laravel框架的用戶,介紹一些laravel框架裡面容器管理方面的使用要點。文章很長,但是內容應該很有用,希望有需要的朋友能看到。php經驗有限,不到位的地方,歡迎幫忙指正。 1. laravel容器基本認識 laravel框架是有一個容器框架,框架應用程式的實例就是一個超大 ...
  • 我要寫幾篇隨筆,為準備學習Java作為自己第一門電腦編程語言的同學總結我認為必需、但在一般的Java教材/課程中並不教授的預備知識。但我並不教你Java本身。我(但願可以)幫你弄明白隨便一本Java教材第一章第一節講的“標準版”、“企業版”、“虛擬機”、“垃圾回收”是什麼。理想的讀者是中學生、家庭 ...
  • ...
  • 電腦網路的分類: 區域網(LAN) 指在一個較小地理範圍內的各種電腦網路設備互聯在一起的通信網路,可以包括一個或多個子網,通常局限在幾千米的範圍之內。 城域網(MAN) 主要由城域範圍內的各個區域網之間互連構成。 廣域網(WAN) 由距離較遠的區域網與城域網互聯構成的通信網路,通常是除了電腦設 ...
  • 題目:古典問題:3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數為多少? 分析:首先我們要明白題目的意思指的是每個月的兔子總對數;假設將兔子分為小中大三種,兔子從出生後三個月後每個月就會生出一對兔子, 那麼我們假定第一個月的兔子為小兔子,第二個月 ...
  • 1.實例變數和類變數 成員變數 VS 局部變數 局部變數(存儲在方法的棧記憶體中) 形參:方法簽名中定義,由方法調用者賦值,隨方法結束而消亡 方法內局部變數:方法內定義,必須在方法內進行顯示初始化,初始化完成後開始生效,隨方法結束而消亡 代碼塊內局部變數:代碼塊內定義,必須代碼塊內進行顯示初始化,初始 ...
  • 概述 ConcurrentHashMap是HashMap的線程安全版本,使用了分段加鎖的方案,在高併發時有比較好的性能。 本文分析JDK1.7中ConcurrentHashMap的實現。 正文 ConcurrentHashMap概述 HashMap不是線程安全的,要實現線程安全除非加鎖,但這樣性能很 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...