JVM堆和棧
這裡只是站在效能監控和分析的角度分享效能測試工程師最關心的JVM知識
不囉嗦,直接總結
-
棧是執行緒私有的,堆是執行緒共享的
-
棧是執行時單位,堆是儲存單位
-
棧解決程式執行問題,堆解決資料儲存問題
-
棧中存的基本資料型別和堆中物件的引用,堆中存的是物件
-
棧代表了處理邏輯,而堆代表了資料
-
棧空間不足丟擲異常:java.lang.StackOverflowError
-
堆空間不足丟擲異常:java.lang.OutOfMemoryError
監控和分析基本思路
- 棧
執行緒是cpu的基本執行單元,而執行緒的執行資訊又儲存在棧空間裡,所以我們對cpu資源的分析核心就是棧資料的分析
cpu常見的瓶頸主要有兩種:
-
cpu資源很容易被消耗掉,導致cpu資源利用率超高
-
不管給多大壓力,cpu的資源利用率總是上不去
這些問題分析的入口基本都是對棧的分析,所以棧善於分析如下問題:
系統無緣無故CPU過高
系統掛起,無響應
系統執行越來越慢
效能瓶頸,如無法充分利用CPU等
執行緒死鎖、死迴圈,餓死等
執行緒數量太多導致系統失敗,如無法建立執行緒等
2.堆
記憶體洩漏,垃圾回收(GC),這些就是對堆的監控和分析了(當然,堆記憶體不足的時候也會導致cpu超高的(例如頻繁full gc),這是後話了)
.class格式的檔案通過JVM執行在不同的作業系統平臺上,那麼這些程式在JVM裡面到底是怎麼執行的呢?JVM又有哪些內容組成?哪些又是我們必須掌握的知識呢?
程式碼執行過程
Java虛擬機器內部體系結構
中文對照:
在上圖的記憶體空間(Java Memory Allocation Area)中,對我們來說最核心兩塊記憶體區域就是堆(Heap)和棧(Stack)了,這也是咱們監控和分析的重點!
在Java中一個執行緒就會相應有一個執行緒棧與之對應,這點很容易理解,因為不同的執行緒執行邏輯有所不同,因此需要一個獨立的執行緒棧。而堆則是所有執行緒共享的,意思就是所有執行緒共用一個堆,執行緒執行過程中所產生的物件都在堆裡面扔著呢!
棧因為是執行單位,因此裡面儲存的資訊都是跟當前執行緒(或程式)相關資訊的。包括區域性變數、程式執行狀態、方法返回值等等;而堆只負責儲存物件資訊。
堆和棧中,棧是程式執行最根本的東西。程式執行可以沒有堆,但是不能沒有棧。而堆是為棧進行資料儲存服務,說白了堆就是一塊共享的記憶體。不過,正是因為堆和棧的分離的思想,才使得Java的垃圾回收成為可能。