天天看點

JVM進階(一)——初識JAVA棧

#JVM進階(一)——初識JAVA棧

  若想使自己編寫的Java程式高效運作,以及進行正确、高效的異常診斷,JVM是不得不談的一個話題。本”JVM進階“專欄大部分内容均來源于經典書籍《深入了解Java虛拟機》。

JVM進階(一)——初識JAVA棧

  下面言歸正傳,本文重點從虛拟機記憶體模型(運作時資料區域)入手。先看圖:

JVM進階(一)——初識JAVA棧

  這是一張比較官方的虛拟機模型圖,今天講的就是虛線框中棧的部分。

  棧是我們最常用的記憶體區域。它主要用來存放基本類型變量,局部變量以及對象的引用。例如:User user = new User();這裡的user就是對象的引用也可以了解為位址,指引着虛拟機要去哪裡找user這個對象。 他們的基本關系如圖:

JVM進階(一)——初識JAVA棧

  由圖可知,當我們将一個對象作為方法的參數時,我們在方法中改變對象的值,也會影響到原來的對象的值,因為我們隻是改變了圖中記憶體區域的值,他的指引(位址)還是一樣的。同時也可以看出,棧的記憶體區域是連續的,有大小限制的,如果超過了就會抛出棧溢出的異常StackOverflowError。

  在每個方法執行的時候,都會建立一個個的棧幀,用于儲存局部變量表,操作數棧,動态連結等資訊(以後都會詳細講解)。每次方法的調用都會對應着一個棧幀,是以可以解釋有我們在寫遞歸程式的時候會不小心報棧溢出的異常,因為棧是有限的,方法調用太多次導緻棧幀堆滿了棧,是以溢出。看下面代碼:

JVM進階(一)——初識JAVA棧

  在參數-Xss128k的情況下的報錯。(eclipse中設定參數:右鍵代碼選擇Run As–>Run Configurations,在Arguments欄下的VM arguments中填入參數,再Apply,再run)

JVM進階(一)——初識JAVA棧

  每次在方法執行完畢的時候,虛拟機會自動釋放掉為該棧所配置設定的空間,在棧中,對應着一個棧幀的出棧。虛拟機會自動配置設定與回收記憶體,是以效率比較高。

  最後做一下棧的總結:

  • 存放基本類型變量,局部變量,對象的引用;
  • 系統自動配置設定與回收記憶體,效率較高,快速,存取速度比堆要快;
  • 是一塊連續的記憶體的區域,有大小限制,如果超過了就會棧溢出,并抛出棧溢出的異常StackOverflowError;
  • Java會自動釋放掉為該變量所配置設定的記憶體空間;

  棧又分為java棧和本地方法棧。顧名思義,本地方法棧自然就是為本地方法提供服務的,java棧是為java服務的。

  注意,JVM棧是每個線程私有的!

聲明:本文圖檔轉載于”這堆幹貨有點猛“。

![這裡寫圖檔描述](https://imgconvert.csdnimg.cn/aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjIwMjEwNjM2NzA1?x-oss-process=image/format,png) ![這裡寫圖檔描述](https://imgconvert.csdnimg.cn/aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjIwMjEwNzMzNDQ2?x-oss-process=image/format,png)