成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

對線面試官:淺聊一下 Java 虛擬機棧?

開發 前端
當一個方法調用另一個方法時,不會再創建一個被調用的方法,而是通過常量池的方法引用來調用,而這個區域存儲的就是運行時常量池的方法引用,這個區域的作用就是將運行時常量池的符號引用轉換成直接引用。

對于 JVM(Java 虛擬機)來說,它有兩個非常重要的區域,一個是棧(Java 虛擬機棧),另一個是堆。堆是 JVM 的存儲單位,所有的對象和數組都是存儲在此區域的;而棧是 JVM 的運行單位,它主管 Java 程序運行的。那么為什么它有這樣的魔力?它存儲的又是什么數據?接下來,我們一起來看。

1.棧定義

我們先來看棧的定義,我們這里的棧指的是 Java 虛擬機棧(Java Virtual Machine Stack)也叫做 JVM 棧,《Java虛擬機規范》對此區域的說明如下:

Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual Machine stack stores frames (§2.6). A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.

In the First Edition of The Java? Virtual Machine Specification, the Java Virtual Machine stack was known as the Java stack.

This specification permits Java Virtual Machine stacks either to be of a fixed size or to dynamically expand and contract as required by the computation. If the Java Virtual Machine stacks are of a fixed size, the size of each Java Virtual Machine stack may be chosen independently when that stack is created.

A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of Java Virtual Machine stacks, as well as, in the case of dynamically expanding or contracting Java Virtual Machine stacks, control over the maximum and minimum sizes.

The following exceptional conditions are associated with Java Virtual Machine stacks:

  • If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
  • If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.

以上內容翻譯成中文的含義如下:

Java 虛擬機棧是線程私有的區域,它隨著線程的創建而創建。它里面保存的是局部變量表(基礎數據類型和對象引用地址)和計算過程中的中間結果。Java 虛擬機的內存不需要連續,它只有兩個操作:入棧和出棧。

Java 虛擬機棧要么大小固定,要么根據計算動態的擴展和收縮。程序員可以對 Java 虛擬機棧進行初始值的大小設置和最大值的設置。

Java 虛擬機棧出現的異常有兩種:

  • 當 Java 虛擬機棧大小固定時,如果程序中的棧分配超過了最大虛擬機棧就會出現 StackOverflowError 異常。
  • 如果 Java 虛擬機棧是動態擴展的,那么當內存不足時,就會引發 OutOfMemoryError 的異常。

2.棧結構

棧是線程私有的,每個線程都有自己的棧(空間),棧中的數據是以棧幀(Stack Frame)的形式存在的,線程會為每個正在執行的方法生成一個棧幀,如下圖所示:

PS:當一個新的方法被調用時,就會在棧中創建一個棧幀,當方法調用完成之后,也就意味著這個棧幀會執行出棧操作。

而棧幀中又存儲了 5 個內容:

  1. 局部變量表(Local Variables);
  2. 操作(數)棧(Operand Stack);
  3. 動態鏈接(Dynamic Linking);
  4. 方法返回地址(Return Address);
  5. 附加信息。

如下圖所示:

棧的整體存儲結構如下圖所示:

2.1 局部變量表

局部變量表也叫做局部變量數組或本地變量表。

局部變量表是一個數組,里面存儲的內容有:

  • 方法參數;
  • 方法內的局部變量,也就是方法內的基本數據類型和對象引用(Reference);
  • 方法返回類型(Return Address)。

接下來我們通過類生成的字節碼來觀察一下局部變量表的內容,首先,我們先來搞一個 main 方法,具體代碼如下:

public static void main(String[] args) {
int num = 0;
LocalVariablesExample lv =
new LocalVariablesExample();
}

然后我們編譯類,再使用“javap -v
LocalVariablesExample.class”查看字節碼生成的內容,其中包含的本地變量表內容如下:

我們通過 JClassLib 也能觀察到局部變量表的信息,如下圖所示為局部變量表的長度:

局部變量表的詳細信息如下:

2.2 操作棧

操作棧也叫做操作數棧或表示式棧,操作數棧主要用于保存計算過程的中間結果,同時作為計算過程中變量臨時的存儲空間。

思考:為什么不把程序執行過程中的中間結果保存到局部變量表,而是保存到操作數棧中呢?

因為局部變量表是數組,而數組的長度是在其創建時就要確定,所以局部變量表在編譯器就決定內容和大小了,那么在程序執行中的這些動態中間結果,是需要新的空間來保存了,而操作數棧就可以實現此功能。

2.3 動態鏈接

動態鏈接也叫做指向運行時常量池的方法引用。

這個區域的概念和作用稍微難理解一點,在每一個棧幀內部都包含一個指向運行時常量池中該棧幀所屬方法的引用。當一個方法調用了另外的其他方法時,就是通過常量池中指向方法的符號引用來表示的,那么動態鏈接的作用就是為了將這些符號引用轉換為調用方法的直接引用。

也就是說:當一個方法調用另一個方法時,不會再創建一個被調用的方法,而是通過常量池的方法引用來調用,而這個區域存儲的就是運行時常量池的方法引用,這個區域的作用就是將運行時常量池的符號引用轉換成直接引用。

2.4 方法返回地址

方法返回地址也叫做方法正常退出或異常退出的定義。

方法返回地址存放的是調用該方法的程序計數器的值。程序計數器里面保存的是該線程要執行的下一行指令的位置。

也就是說:在一個方法中調用了另一個方法,當被調用的方法執行完之后,要執行的下一行指令就是保存在此區域的。

2.5 附加信息

此區域在很多教程上會被省略,因為此區域有可能有數據,也有可能沒有數據。這些附加信息是和 Java 虛擬機實現相關的一些信息。例如,對程序調試提供支持的信息。

總結

棧作為 Java 虛擬機中最核心的組成部分之一,它包含了以下 5 部分的內容:

  1. 局部變量表(Local Variables):主要存儲的是方法內的基本數據類型和對象引用;
  2. 操作(數)棧(Operand Stack):主要用于保存計算過程的中間結果,同時作為計算過程中變量臨時的存儲空間;
  3. 動態鏈接(Dynamic Linking):存放的是指向運行時常量池的方法引用;
  4. 方法返回地址(Return Address):存放的是調用該方法的程序計數器的值;
  5. 一些附加信息:存儲了一些和 Java 虛擬相關的數據,比如程序的調試數據。

參考 & 鳴謝

《阿里巴巴Java開發手冊》

《尚硅谷JVM》

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2021-04-14 18:58:01

虛擬機 Java內存

2024-04-16 08:15:07

CHAR數據字符串

2023-09-12 14:56:13

MyBatis緩存機制

2024-03-25 13:02:00

MySQL索引主鍵

2022-06-07 12:03:33

Java內存模型

2023-02-07 06:47:58

JVM 模塊Java 虛擬機

2021-07-28 10:08:19

類加載代碼塊面試

2025-03-10 07:05:07

2021-08-02 07:57:02

內存Go語言

2024-02-21 07:40:17

JVM內存虛擬機

2018-04-04 14:43:27

虛擬機保護技術

2024-08-05 10:13:59

MySQL大數據優化

2021-04-21 21:06:11

數據結構

2022-06-06 15:33:20

線程Java釋放鎖

2023-02-08 08:32:41

輪詢鎖

2023-02-18 13:34:14

Nacos健康檢查機制

2021-11-08 15:59:01

MyBatis關聯開發

2021-08-28 09:06:11

Dubbo架構服務

2023-12-29 13:45:00

2024-01-29 10:08:11

零拷貝Zero-copyCPU 拷貝
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品无码一区二区三区 | 婷婷综合 | 国产精品成人在线观看 | 欧美精品一区二区三区在线播放 | 欧美成人精品一区二区三区 | 乳色吐息在线观看 | 日韩高清中文字幕 | 午夜寂寞影院在线观看 | 91精品久久久久久久久中文字幕 | 午夜免费视频观看 | 久草99| 国产精品国产a级 | 欧美日韩免费一区二区三区 | 一区二区三区四区视频 | 成人在线影视 | 国产精品一区二区三区在线 | 日日骚网 | 午夜影院在线观看版 | www.天天操.com| 中文字幕国产第一页 | 久久一区二区av | 久久久男人的天堂 | 国产精品久久久久久久久久久久午夜片 | 成人免费小视频 | 北条麻妃99精品青青久久 | 亚洲色图第一页 | 爱爱免费视频网站 | 亚洲激情在线观看 | 欧美激情区 | 国产一区在线视频 | 97精品超碰一区二区三区 | 99久久精品一区二区毛片吞精 | 农夫在线精品视频免费观看 | a在线观看 | 国产黄色精品 | 亚洲性视频网站 | 亚洲综合婷婷 | 久久精品国产一区二区 | 91免费在线视频 | 婷婷色综合 | 欧美不卡一区二区 |