JVM stack and heap

閱讀時間約 4 分鐘

Java Visualizer

使用 intelliJ IDE 開發工具的話, 建議可以安裝 java-visualizer 來觀察。
首先關注 a, b 這 2 個變數, 於 call stack 區塊的顯示, 變數 a 是 primitive type 可以直接存放於 stack 空間, 原本以為 b 會有 Objects 紀錄, 原因是 Integer 在編譯為 byte code 時會變成 byteshort 存入 stack, 真是太神奇了 Jack。
可以參照 StackOverflow 解釋, 但我沒有深究
而變數 list 則是明顯的產生一個 Reference 參照到 Objects 裡面的 ArrayList 物件。

JVM 什麼時候使用 stack 什麼時候使用 heap ?

我個人覺得比較好理解的方式是, 從 StackOverflowErrorOutOfMemoryError 這兩個錯誤去認識 StackHeap
StackOverflowError 觸發的條件在於產生大量的 stack memory 直到超過 JVM 設定的 stack 大小。簡單測試如下:
public static void main(String[] args) {
recursive(1);
}
// 這裡是一個無限遞迴, 每次遞迴都會使用一塊 stack 空間
private static void recursive(int i) {
System.out.println("print: " + i);
recursive(++i);
}
依據 Oracle 的文件描述, stack 可以是固定大小或是動態擴展的, 可以使用 java -Xss1M 這樣的設定去啟動 JVM, 宣告 stack 大小為 1Mb 空間。
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.
-Xss 的設定會依據 JVM 的環境, 或是 OS 的環境而有所差異, 這是 Oracle 提供的簡略參考對照表
https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/jrdocs/refman/optionX.html#wp1024112
OutOfMemoryError 的觸發條件, 源自於超過 Heap 使用上限, 搭配 -Xmx1M 很容易就達到。
public static void main(String[] args) {
  // 由於限制了 1Mb 的 Heap 使用量, 所以根本無法產生大空間的 intArray
Integer[] intArray = new Integer[Integer.MAX_VALUE];
System.out.println(intArray);
}

總結

Stack 的空間用於 primitive type 或是用於指向 object reference, 依據官方文件描述, 每個 threads 都會有自己的 stack; 而 Heap 空間用於 Objects 實際上使用的空間。
若採用多執行緒的設計, Heap 空間就需要特別留意 OOM 問題, 特別是在 Microservice 的環境下, Replica 的設定沒有估計, 很容易就不小心吃掉大量記憶體, 導致同一個 Node 底下的服務因為記憶體不夠而不停重啟。
// JVM 使用的記憶體最大值
N-threads * Xms size = JVM Heap Size
    avatar-img
    0會員
    2內容數
    留言0
    查看全部
    avatar-img
    發表第一個留言支持創作者!
    你可能也想看
    Google News 追蹤
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    當你在 Kotlin 程式語言中定義一個有預設參數的函數功能,並給它預設值,@JvmOverloads 可以自動產生多個重載版本的 Java 方法,每個版本都省略了部分參數,讓 Java 代碼可以更簡潔地呼叫這些方法,而不需要填寫所有參數。不會因為沒有預設值,而顯示錯誤。
    Thumbnail
    Companion Object 是 Kotlin 中一個特殊的物件,用來在類別內部創建靜態成員。當你在一個類別內部建立 companion object 時,裡面的成員就可以像 Java 中的靜態成員一樣被使用,不需要通過該類別的實例來訪問。 結合使用 @JvmStatic 和 Companion
    Thumbnail
    當你在 Kotlin 中使用 val 或 var 定義一個屬性時,在 Java 中預設會轉換為 getter 和 setter 方法。如果你希望直接在 Java 中存取這個屬性,可以使用 @JvmField 註解。這會讓 Kotlin 編譯器將屬性生成為公開的,而非生成 getter 和 sette
    Thumbnail
    在混合開發的 Java 和 Kotlin 項目中,函數命名衝突是一個常見的問題。這時可以利用@JvmName 註解來解決這樣的狀況。@JvmName 註解非常實用,它可以讓你更靈活地控制在 JVM 平台上生成的 Kotlin 程式碼名稱。
    Thumbnail
    每個method都有一個自己的stack Instance Variable 會存在heap中 Local Variable 會存在stack中
    Thumbnail
    願耶和華的慈愛和聖靈的感動與各位同在,主佑各位。 GOD BLESS EVERYONE,IN JESUS NAME,AMEN。 📷
    Thumbnail
    兩年前Magni一分二之後,價格調低后就開始慢慢買進。此股數量雖是我portfolio的老大,但紙上虧損卻是老二。於是,Q3季報出爐,又再乖乖查閲,到底發生了什麽事?
    Thumbnail
    Inari Stock Analysis for Q2 2022 (Financial Period Ended 31 December 2021) Not for investment’s advice purpose (無投資建議)
    Thumbnail
    如果對 Hill O‘Many 古石陣沒有一點點了解的話,那麼這個地方對於許多的遊客可能會覺得很無趣,所以很慶幸我們當初決定要請一個專人的司機導遊帶著我們玩蘇格蘭高地。 看完這個有久遠年代的古石頭陣後,我們的高地之旅繼續進行著,一路繼續往蘇格蘭最東北方的鄧肯斯比 (Duncansby) 前進
    Thumbnail
    Jamstack 是個描述前後端分離下的字彙,因為老外就愛發明新字,所以這篇我們來用 Jamstack 的角度來看前後端分離。
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    當你在 Kotlin 程式語言中定義一個有預設參數的函數功能,並給它預設值,@JvmOverloads 可以自動產生多個重載版本的 Java 方法,每個版本都省略了部分參數,讓 Java 代碼可以更簡潔地呼叫這些方法,而不需要填寫所有參數。不會因為沒有預設值,而顯示錯誤。
    Thumbnail
    Companion Object 是 Kotlin 中一個特殊的物件,用來在類別內部創建靜態成員。當你在一個類別內部建立 companion object 時,裡面的成員就可以像 Java 中的靜態成員一樣被使用,不需要通過該類別的實例來訪問。 結合使用 @JvmStatic 和 Companion
    Thumbnail
    當你在 Kotlin 中使用 val 或 var 定義一個屬性時,在 Java 中預設會轉換為 getter 和 setter 方法。如果你希望直接在 Java 中存取這個屬性,可以使用 @JvmField 註解。這會讓 Kotlin 編譯器將屬性生成為公開的,而非生成 getter 和 sette
    Thumbnail
    在混合開發的 Java 和 Kotlin 項目中,函數命名衝突是一個常見的問題。這時可以利用@JvmName 註解來解決這樣的狀況。@JvmName 註解非常實用,它可以讓你更靈活地控制在 JVM 平台上生成的 Kotlin 程式碼名稱。
    Thumbnail
    每個method都有一個自己的stack Instance Variable 會存在heap中 Local Variable 會存在stack中
    Thumbnail
    願耶和華的慈愛和聖靈的感動與各位同在,主佑各位。 GOD BLESS EVERYONE,IN JESUS NAME,AMEN。 📷
    Thumbnail
    兩年前Magni一分二之後,價格調低后就開始慢慢買進。此股數量雖是我portfolio的老大,但紙上虧損卻是老二。於是,Q3季報出爐,又再乖乖查閲,到底發生了什麽事?
    Thumbnail
    Inari Stock Analysis for Q2 2022 (Financial Period Ended 31 December 2021) Not for investment’s advice purpose (無投資建議)
    Thumbnail
    如果對 Hill O‘Many 古石陣沒有一點點了解的話,那麼這個地方對於許多的遊客可能會覺得很無趣,所以很慶幸我們當初決定要請一個專人的司機導遊帶著我們玩蘇格蘭高地。 看完這個有久遠年代的古石頭陣後,我們的高地之旅繼續進行著,一路繼續往蘇格蘭最東北方的鄧肯斯比 (Duncansby) 前進
    Thumbnail
    Jamstack 是個描述前後端分離下的字彙,因為老外就愛發明新字,所以這篇我們來用 Jamstack 的角度來看前後端分離。