java 内存模型程序计数器和虚拟机栈
文章目錄
- 一、程序計數器
- 二、虛擬機棧
java程序運行過程中會把它所管理的區域劃分不同的數據區域,其中包括方法區、虛擬機棧、本地方法棧、堆、程序計數器。
一、程序計數器
程序計數器是一塊 較小 的內存空間,它可以看做是當前線程所執行的字節碼的 行號指示器
;在虛擬機的概念模型里(僅僅是概念模型,各種虛擬機可能會通過一些更高效的方式去實現),字節碼解釋器工作時,就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳準、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。摘自 周志明版 《深入理解java虛擬機》 P39
簡單的理解就是是程序計數器保證了程序的正常執行 。
程序計數器特點 :
1.線程私有
2.生命周期是隨線程啟動而啟動,線程消亡而消亡、
3.是java虛擬機規范里面, 唯一 一個 沒有規定任何 OutOfMemoryError 情況的區域
程序計數器,可以看做是當前線程執行的字節碼的 行號指示器 ,這句話;要理解這句話,需要先知道字節碼文件長什么樣子,看下面的代碼
public class Hello {public void say(){Hello he = new Hello();System.out.println("hello world");} }Hello類的字節碼為:
public class Hello {public Hello();Code:0: aload_01: invokespecial #1 4: returnpublic void say();Code:0: new #2 // class Hello3: dup4: invokespecial #3 // Method "<init>":()V7: astore_18: getstatic #4 11: ldc #5 // String hello world13: invokevirtual #6 16: return }代碼中0、3、4、7等的就是字節碼指令的偏移地址,偏移地址對應的bipush 等等是jvm 中的操作指令,這是入棧指令。執行到方法say()時在當前的線程中會創建相應的程序計數器,在計數器中為存放執行地址 0 3 4…等等。
這也說明在我們程序運行過程中計數器中改變的只是值,而不會隨著程序的運行需要更大的空間,也就不會發生溢出情況。
二、虛擬機棧
java虛擬機棧特點:
1、Java 虛擬機棧(Java Virtual Machine Stacks)是線程私有的,生命周期隨著線程,線程啟動而產生,線程結束而消亡。
2、Java 虛擬機棧描述的是 Java 方法執行的內存模型,用于存儲棧幀。線程啟動時會創建虛擬機棧,每個方法在執行時會在虛擬機棧中創建一個棧幀,用于存儲局部變量表、操作數棧、動態連接、方法返回地址、附加信息等信息。每個方法從調用到執行完成的過程,就對應著一個棧幀在虛擬機棧中的入棧(壓棧)到出棧(彈棧)的過程。
3、Java 虛擬機規范即允許 Java 虛擬機棧被實現成固定大小(-Xss),也允許通過計算結果動態來擴容和收縮大小。如果采用固定大小的 Java 虛擬機棧,那每個線程的 Java 虛擬機棧容量可以在線程創建的時候就已經確定。
Java 虛擬機棧會出現的異常
1、如果線程請求分配的棧容量超過了 Java 虛擬機棧允許的最大容量,Java 虛擬機將會拋出 StackOverflowError 異常。
2、如果 Java 虛擬機棧可以動態擴展,并且在嘗試擴展的時候無法申請到足夠的內存,或者在創建新的線程時沒有足夠的內存去創建對應的虛擬機棧,那 Java 虛擬機將拋出一個 OutOfMemoryError 異常。
Java 虛擬機棧執行過程
可參考文章:https://blog.csdn.net/azhegps/article/details/54092466
總結
以上是生活随笔為你收集整理的java 内存模型程序计数器和虚拟机栈的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBatch job执行流程分
- 下一篇: java 内存模型堆和本地方法