JVM内存结构|虚拟机栈
生活随笔
收集整理的這篇文章主要介紹了
JVM内存结构|虚拟机栈
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
定義
每個線程運行時所需要的內存稱為虛擬機棧
- 每個棧由多個棧幀組成,對應著每次方法調用時所占用的內存
- 每個線程只能有一個活動棧幀,對應著當前正在執行的那個方法
- Java 虛擬機棧(Java Virtual Machine Stacks):描述的是Java方法執行的內存模型:每個方法在執行的同時都會創建一個幀棧(Stack Frame)用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中入棧到出棧的過程。它的線程也是私有的,生命周期與線程相同。
- 局部變量表存放了編譯期可知的各種基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用和 returnAddress 類型(指向了一條字節碼指令的地址)。
- Java 虛擬機棧的局部變量表的空間單位是槽(Slot),其中64位長度的double 和long
類型會占用兩個Slot。局部變量表所需內存空間在編譯期完成分配,當進入一個方法時,該方法需要在幀中分配多大的局部變量是完全確定的,在方法運行期間不會改變局部變量表的大小。 - Java虛擬機棧有兩種異常狀況:如果線程請求的棧的深度大于虛擬機所允許的深度,將拋出StackOverflowError異常;
- 如果擴展時無法申請到足夠的內存,就會拋出OutOfMemoryError異常。
問題辨析
- 垃圾回收是否涉及棧內存?
不涉及。虛擬機棧里的棧幀即對應代碼中的一個方法。代碼運行的過程,即棧幀入棧出棧的過程。
一個方法執行完,棧幀出棧后,即被銷毀。只有入棧出棧這樣簡單的操作,不需要設計復雜的垃圾回收算法來回收。隨著方法的執行,線程的結束正?;厥占纯伞?/li> - 棧內存分配越大越好嗎?
不會,棧內存越大線程數目會越少,并不會提高程序的運行效率,但能增加遞歸的調用次數。 - 方法內的局部變量是否線程安全?
如果方法內局部變量沒有逃離方法的作用訪問,它是線程安全的
如果是局部變量引用了對象,并逃離方法的作用范圍,需要考慮線程安全
棧內存溢出
java.lang.StackOverFlowError
可能原因:
-
棧幀過多導致棧內存溢出(方法的遞歸調用次數過多會導致)
-
棧幀過大導致棧內存溢出(一個方法的局部變量和方法參數過多,局部變量和方法參數在棧幀中)(不容易出現)
線程運行診斷
案例1:某程序CPU占用過多(Linux下)
定位
-
用top定位哪個進程對cpu的占用過高
-
ps H -eo pid,tid,%cpu | grep 進程id (用ps命令進一步定位是哪個線程引起的cpu占用過高)
-
jstack 進程id 可以根據線程id 找到有問題的線程,進一步定位到問題代碼的源碼行號(查詢出的線程id是以十六進制表示的)
案例2:程序運行很長時間沒有結果
- 使用nohup命令運行Java程序獲得進程id
- 使用jstack 進程id,根據線程id 找到有問題的線程,進一步定位到問題代碼的源碼行號
總結
以上是生活随笔為你收集整理的JVM内存结构|虚拟机栈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 守望先锋源氏怎么玩(《守望先锋》归来官方
- 下一篇: php fclose函数怎么用