1. 程式人生 > 其它 >JVM堆和棧

JVM堆和棧

這裡只是站在效能監控和分析的角度分享效能測試工程師最關心的JVM知識

不囉嗦,直接總結

  • 棧是執行緒私有的,堆是執行緒共享的

  • 棧是執行時單位,堆是儲存單位

  • 棧解決程式執行問題,堆解決資料儲存問題

  • 棧中存的基本資料型別和堆中物件的引用,堆中存的是物件

  • 棧代表了處理邏輯,而堆代表了資料

  • 棧空間不足丟擲異常:java.lang.StackOverflowError

  • 堆空間不足丟擲異常:java.lang.OutOfMemoryError

監控和分析基本思路

執行緒是cpu的基本執行單元,而執行緒的執行資訊又儲存在棧空間裡,所以我們對cpu資源的分析核心就是棧資料的分析

,也就是經常說的對執行緒做dump(拍快照)。

cpu常見的瓶頸主要有兩種:

  • cpu資源很容易被消耗掉,導致cpu資源利用率超高

  • 不管給多大壓力,cpu的資源利用率總是上不去

這些問題分析的入口基本都是對棧的分析,所以棧善於分析如下問題:

系統無緣無故CPU過高

系統掛起,無響應

系統執行越來越慢

效能瓶頸,如無法充分利用CPU等

執行緒死鎖、死迴圈,餓死等

執行緒數量太多導致系統失敗,如無法建立執行緒等

2.堆

記憶體洩漏垃圾回收(GC),這些就是對堆的監控和分析了(當然,堆記憶體不足的時候也會導致cpu超高的(例如頻繁full gc),這是後話了)


.class格式的檔案通過JVM執行在不同的作業系統平臺上,那麼這些程式在JVM裡面到底是怎麼執行的呢?JVM又有哪些內容組成?哪些又是我們必須掌握的知識呢?

程式碼執行過程

Java虛擬機器內部體系結構

中文對照:

在上圖的記憶體空間(Java Memory Allocation Area)中,對我們來說最核心兩塊記憶體區域就是堆(Heap)和棧(Stack)了,這也是咱們監控和分析的重點!

在Java中一個執行緒就會相應有一個執行緒棧與之對應,這點很容易理解,因為不同的執行緒執行邏輯有所不同,因此需要一個獨立的執行緒棧。而堆則是所有執行緒共享的,意思就是所有執行緒共用一個堆,執行緒執行過程中所產生的物件都在堆裡面扔著呢!

棧因為是執行單位,因此裡面儲存的資訊都是跟當前執行緒(或程式)相關資訊的。包括區域性變數、程式執行狀態、方法返回值等等;而堆只負責儲存物件資訊。

堆和棧中,棧是程式執行最根本的東西。程式執行可以沒有堆,但是不能沒有棧。而堆是為棧進行資料儲存服務,說白了堆就是一塊共享的記憶體。不過,正是因為堆和棧的分離的思想,才使得Java的垃圾回收成為可能。