java虛擬機棧空間

翻譯自:https://www.geeksforgeeks.org/java-virtual-machine-jvm-stack-area/

在線程創建的時候,JVM會爲每個線程創建一個單獨的棧空間。JVM的棧內存不需要是連續的。JVM在棧上會進行兩個操作:壓入和彈出棧幀。對於一個特定的線程來說,棧被稱爲運行時棧(Run - Time Stack)。這個線程調用的每個方法會被存儲在響應的運行時棧裏,包括了參數,局部變量,計算媒介和其他數據。當一個方法運行結束的時候,相應的棧條目也會被移除掉。在一個線程的所有方法調用結束的時候,JVM會清空相應的棧內存,並在終止線程之前回收棧空間。在棧內存裏的數據只可以被相對應的線程訪問,其餘的線程無法訪問。所以我們可以說局部數據是線程安全的。每個棧的條目會被叫做棧幀(Stack Frame)或者活動記錄(Activation Record)。
在這裏插入圖片描述

棧幀結構

棧幀主要由部分組成:局部變量數組,操作數棧和棧數據區。當JVM調用一個Java方法的時候,首先它會檢測類數據來決定字節數(局部變量數組和操作數棧的佔用大小,每個獨立的方法會進行一次單獨的測算),會在局部變量數組和操作數棧中需要用到這個大小。隨後JVM就會創建合適大小的棧幀用來作方法調用和入棧操作。

1. 局部變量數組 Local Variable Array (LVA):

  • 棧幀的局部變量部分是由爲索引0開始的字節數組構成。
  • 它包含了所有的方法參數和局部變量。
  • 在數組中的每個插槽或條目大小是4個字節。
  • int,float和引用類型在數組中全部佔用一個條目或插槽,例如,4字節大小。
  • double和long類型的數據在數組中佔用2個連續條目,例如,總共8字節大小。
  • byte,short和char類型在存儲之前會被轉化爲int類型並且佔用1個插槽,例如,4字節大小。
  • 但是存儲boolean類型值的方式在不同的JVM中有不同的實現。在大多數JVM的實現中boolean類型在局部變量數組中佔用一個插槽。
  • 參數會首先被放置如局部變量數組中,順序是它們在方法中聲明的順序。
  • 例如: 一個類有一個方法叫做bike(),bike()方法的局部變量數組的存儲情況如下圖所示:
// Class Declaration
class Example
{
  public void bike(int i, long l, float f, 
               double d, Object o, byte b)
  {
     return 0;
  } 
}

在這裏插入圖片描述

2. 操作數棧 Operand Stack (OS):

  • JVM使用操作數棧作爲運行的工作空間或者我們也可以說用來存儲計算的中間結果。
  • 操作數棧也像局部變量數組一樣組織爲一個數組。但是它不是使用索引來訪問的而是由一些指令來訪問,這些指令可以把值推進棧中,也可以把值從棧中彈出並且做一些我們需要的操作。
  • 例如:下面是一個例子,這個例子把兩個int類型的局部變量進行相減,並且將結果int值存儲在第三個局部變量中:
    在這裏插入圖片描述
    這裏的iload_0iload_1這兩個指令會將值從局部變量數組中推入到操作數棧中。 isub指令會將這兩個值相減然後把值存回到操作數棧中。然後在istore_2指令執行之後,結果值會從操作數棧中被彈出然後存入局部變量數組的第2個位置(索引爲2)。
    在這裏插入圖片描述

3. 棧幀數據區 Frame Data (FD):

  • 棧數據區包含了所有的符號引用(常量池解析)和普通方法的return位置,該return與特定的方法關聯,用來跳轉回去。
  • 它也包含了一個到異常表的引用,可以在異常發生的提供catch代碼塊的信息。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章