JVM stack and heap

更新於 發佈於 閱讀時間約 5 分鐘
raw-image

Java Visualizer

使用 intelliJ IDE 開發工具的話, 建議可以安裝 java-visualizer 來觀察。

raw-image

首先關注 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);
}
raw-image

依據 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 提供的簡略參考對照表

raw-image

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
留言分享你的想法!
avatar-img
jyuto的沙龍
0會員
2內容數
你可能也想看
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
此章節旨在介紹Java程式語言中的各種資料型別,包括基本型別、引用型別、集合型別、陣列型別、字典型別等。它還講解了如何在Java中進行型別轉換和自定義型別,並提供了相關的程式碼示例。
Thumbnail
此章節旨在介紹Java程式語言中的各種資料型別,包括基本型別、引用型別、集合型別、陣列型別、字典型別等。它還講解了如何在Java中進行型別轉換和自定義型別,並提供了相關的程式碼示例。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
此章節旨在介紹Java的基本語法、註解和變數的使用。透過學習,讀者將了解Java程式的基本結構、程式進入點的定義、如何撰寫單行和多行註解,以及如何宣告和初始化變數。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
這篇文章的目的是對Java程式設計語言進行介紹,包括它的特性、應用範疇、主要使用者,以及相關的學習資源和常見的庫與框架。此外,它也提供了一些學習Java的渠道,以及與Java相關的其他知識。
Thumbnail
老實說,看到 Java Sream API 讓我感到相當親切,這應該跟我研究所多年的研究題目是 visual dataflow language 有關,Java Stream API 把迴圈給內化了,每個 operation 的重點是要做什麼,大大提高了程式的抽象化程度和可讀性。
Thumbnail
老實說,看到 Java Sream API 讓我感到相當親切,這應該跟我研究所多年的研究題目是 visual dataflow language 有關,Java Stream API 把迴圈給內化了,每個 operation 的重點是要做什麼,大大提高了程式的抽象化程度和可讀性。
Thumbnail
在前端開發中,因為瀏覽器可以迅速啟動與關閉的特性,再加上 JavaScript 的 Garbage Collection 垃圾回收機制,常常讓前端開發者忽略了 JavaScript 的記憶體管理機制與 Memory Leak 帶來的危險性,有時應用的效能瓶頸可能就因此產生了。
Thumbnail
在前端開發中,因為瀏覽器可以迅速啟動與關閉的特性,再加上 JavaScript 的 Garbage Collection 垃圾回收機制,常常讓前端開發者忽略了 JavaScript 的記憶體管理機制與 Memory Leak 帶來的危險性,有時應用的效能瓶頸可能就因此產生了。
Thumbnail
這次分享資料形態中的資料型別部分,在VC#流程架構介紹中有提到它如同中文有不同的詞性,那C#程式中有哪些型別呢?我們就來看一看。 一、常用的資料型別 當然還有自訂義的型別這就要看怎麼定義了,之後看內容狀況再來提,那麼資料型態是為了要做宣告用途,告訴電腦你的資料是屬於什麼類別的,這樣在做後續資料時程式
Thumbnail
這次分享資料形態中的資料型別部分,在VC#流程架構介紹中有提到它如同中文有不同的詞性,那C#程式中有哪些型別呢?我們就來看一看。 一、常用的資料型別 當然還有自訂義的型別這就要看怎麼定義了,之後看內容狀況再來提,那麼資料型態是為了要做宣告用途,告訴電腦你的資料是屬於什麼類別的,這樣在做後續資料時程式
Thumbnail
介紹 原始碼(source code)→編譯器→中繼語言(MSIL)→CLR→電腦看得懂的語言(Native code) 所以我們可以知道,CLR( Common Language Runtime ):是 .NET Framework 的虛擬機器元件 (virtual machine compone
Thumbnail
介紹 原始碼(source code)→編譯器→中繼語言(MSIL)→CLR→電腦看得懂的語言(Native code) 所以我們可以知道,CLR( Common Language Runtime ):是 .NET Framework 的虛擬機器元件 (virtual machine compone
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News