Java 棧 Java 虛擬機棧:Java Virtual Machine Stacks,每個線程運行時所需要的內存
每個方法被執行時,都會在虛擬機棧中創建一個棧幀 stack frame(一個方法一個棧幀)
Java 虛擬機規範允許 Java 棧的大小是動態的或者是固定不變的
虛擬機棧是每個線程私有的,每個線程只能有一個活動棧幀,對應方法調用到執行完成的整個過程
每個棧由多個棧幀(Frame)組成,對應着每次方法調用時所佔用的內存,每個棧幀中存儲着:
局部變量表:存儲方法裏的 Java 基本數據類型以及對象的引用
動態鏈接:也叫指向運行時常量池的方法引用
方法返回地址:方法正常退出或者異常退出的定義
操作數棧或表達式棧和其他一些附加信息
設置棧內存大小:-Xss size -Xss 1024k
在 JDK 1.4 中默認為 256K,而在 JDK 1.5+ 默認為 1M
虛擬機棧特點:
棧內存不需要進行GC,方法開始執行的時候會進棧,方法調用後自動彈棧,相當於清空了數據
棧內存分配越大,可用的線程數越少(內存越大,每個線程擁有的內存越大)
方法內的局部變量是否線程安全:
如果方法內局部變量沒有逃離方法的作用訪問(即在方法的作用範圍內,是局部變量的時候),它是線程安全的(逃逸分析)
如果是局部變量引用了對象,並逃離方法的作用範圍,或者返回了對象,就需要考慮線程安全
異常:
棧幀過多導致棧內存溢出 (超過了棧的容量),會拋出 OutOfMemoryError 異常
當線程請求的棧深度超過最大值,會拋出 StackOverflowError 異常
局部變量 局部變量表也被稱之為局部變量數組或本地變量表,本質上定義為一個數字數組,主要用於存儲方法參數和定義在方法體內的局部變量
表是建立在線程的棧上,是線程私有的數據,因此不存在數據安全問題
表的容量大小是在編譯期確定的,保存在方法的 Code 屬性的 maximum local variables 數據項中
表中的變量只在當前方法調用中有效,方法結束棧幀銷燬,局部變量表也會隨之銷燬
表中的變量也是重要的垃圾回收根節點,只要被表中數據直接或間接引用的對象都不會被回收
局部變量表最基本的存儲單元是 slot(變量槽):
參數值的存放總是在局部變量數組的 index0 開始,到數組長度 -1 的索引結束,JVM 為每一個 slot 都分配一個訪問索引,通過索引即可訪問到槽中的數據
存放編譯期可知的各種基本數據類型(8種),引用類型(reference),returnAddress 類型的變量
32 位以內的類型只佔一個 slot(包括 returnAddress 類型),64 位的類型(long 和 double)佔兩個 slot
局部變量表中的槽位是可以重複利用的,如果一個局部變量過了其作用域,那麼之後申明的新的局部變量就可能會複用過期局部變量的槽位,從而達到節省資源的目的
操作數棧 棧:可以使用數組或者鏈表來實現
操作數棧:在方法執行過程中,根據字節碼指令,往棧中寫入數據或提取數據,即入棧(push)或出棧(pop)
保存計算過程的中間結果,同時作為計算過程中變量臨時的存儲空間,是執行引擎的一個工作區
Java 虛擬機的解釋引擎是基於棧的執行引擎,其中的棧指的就是操作數棧
如果被調用的方法帶有返回值的話,其返回值將會被壓入當前棧幀的操作數棧中
棧頂緩存技術 ToS(Top-of-Stack Cashing):將棧頂元素全部緩存在 CPU 的寄存器中,以此降低對內存的讀/寫次數,提升執行的效率
基於棧式架構的虛擬機使用的零地址指令更加緊湊,完成一項操作需要使用很多入棧和出棧指令,所以需要更多的指令分派(instruction dispatch)次數和內存讀/寫次數,由於操作數是存儲在內存中的,因此頻繁地執行內存讀/寫操作必然會影響執行速度,所以需要棧頂緩存技術 ———————————————— 版權聲明:本文為CSDN博主「向着五星的方向」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/qq_69748833/article/details/137799873