JVM內存空間劃分與做用詳解

在以前已經對Java的字節碼進行了很是詳細而又系統的學習了,接下來開啓jvm內存相關的新篇章,在一個新知識開頭以前確定得理論化的對其進行一個總體的介紹,因此摒棄浮躁,先來看看相關的理論,主要是看一下JVM內存的相關結構:html

虛擬機棧:每個方法在執行的過程當中都會生成一個棧幀(Stack Frame,在以前【http://www.javashuo.com/article/p-nvbhpevw-dt.html】已經有介紹過)這個數據結構。web

程序計數器(Program Counter):它佔據的空間是比較小的,主要是描述線程執行字節碼第一行執行完了以後,下一行字節碼在哪。數據結構

本地方法棧:主要用於處理本地方法。jvm

堆(Heap):這是JVM所管理最大的內存空間,在Java當中咱們都是通用引用來操做對象的,而對象自己是位於堆上面,而引用則是位於虛擬機棧上面,因此引用自己是個變量,因此在Java中必定是經過引用來獲取到這個對象而後去操縱它。下面用一個小的示意圖來理論引用與對象它們之間的關係。學習

其實引用指向對象是有兩種形態的,上面只是一個粗略的形態,其實在堆中一部份存放的是對象實例自己的數據,另外一部分則是元數據(也就是class數據),而元數據只有一份,它是存放在另一個位置的,該位置叫方法區,以下:線程

而實際實現第一種形態多是這樣:指針

而第二種形態可能爲:htm

對於Oracle的Hotspot虛擬機採用的是第二種形態,那對於這二種形態有啥區別呢?其實區別仍是挺大的,對於JVM垃圾回收來講,當對像被回收以後可能會形成對象的移動,用個形象的未例圖來表述這個移動:對象

對於對象的移動,假如採用第一種形態,因爲是用一個指針來指向對象,因此指針的值也會發生變化,而對於堆內存而言發生垃圾回收的頻率是至關之高的,因此該指向變量的指針會頻繁發生變化;而若是採用第二種形態則沒有這個問題,由於ref是直接指向的對象自己,當對象移動時則ref只是指向的位置會發生變化,值仍是同樣的,以下:blog

因此通過對比,也能發現第二種形態會更好,這也是Oracle的Hotspot爲啥採用第二種的緣由。

方法區(Method Area):存儲元信息。咱們對於垃圾收集器可能常常會聽到一個叫永久代(Permanent Generation)的概念,因此永久代固然就是不多會被回收,因此會將方法區稱爲永久代,可是從JDK1.8開始,已經完全廢棄了永久代了,使用元空間(Meta Space)代替。

運行時常量池:方法區的一部內容,這個在我們以前的字節碼學習中已經詳細學習過。

直接內存:Direct Memory,它並非由JVM所管理的一塊區域,而是由系統所管轄的,只不過是JVM向系統申請了這塊內存。

以上是從宏觀的角度來審視JVM的內存結構,在以後會結合實踐對這些理論進行進一步鞏固!

相關文章
相關標籤/搜索