Java虛擬機器--Jvm記憶體結構

來源:互聯網
上載者:User

標籤:還需   根據   stack   java語言   cpu   str   bubuko   AC   緩衝   

1.JVM是什麼?

  JVM:Java Virtual Mechinal(Java虛擬機器).它是一個虛構的電腦,是通過在實際的電腦上類比各種功能來實現的。JVM的主要工作是解釋自己的指令集(位元組碼,如java源碼編譯成class檔案在虛擬機器上運行)並映射到本地的CPU指令集或OS的系統調用。Java語言跨平台的本質就是不同的作業系統使用不同的JVM映射規則,使其與作業系統無關,從而實現跨平台。

2.JVM的記憶體結構是什麼樣子?

  Java虛擬機器在運行Java程式的時候,會把它所管理的記憶體劃分為若干個不同的資料區域,:

      

3.那麼接下來每個資料區域都是做什麼的呢?

  (1).程式計數器:是一塊較小的記憶體空間,可以看作是當前線程所執行位元組碼的行號指標。尤其在多線程的情況下,尤為重要。Java虛擬機器的多線程是通過線程輪流切換並分配處理器執行時間的方式來實現的,即在任何一個確定時刻,一個處理器只會執行一條線程,當線程切換後就需要恢複到正確位置,因此,程式計數器要實現線程隔離,每個線程都有自己的專屬的計數器。值得注意的是:此記憶體地區是唯一一個在Java虛擬機器規範中沒有規定任何OutOfMemoryError情況的地區。

  (2).堆:此記憶體地區是Java虛擬機器管理的最大一塊記憶體,同時也是線程共有的,在虛擬機器啟動時建立。它用來儲存Java中的對象執行個體(無論成員變數,局部變數還是類變數,它們只想的對象都儲存在堆記憶體中),幾乎所有的對象執行個體都在這分配記憶體。同時這裡也是GC的主要區域。從記憶體回收的角度來看,由於收集器基本都採用分代收集法,所以在Java堆中還可以細分為:新生代和老年代(可以理解為不用代的對象記憶體位置是不同的);再細緻可分為:Eden空間,From Survivor空間,To Survivor空間(8:1:1)。從記憶體配置的角度來看,線程共用的Java堆中可能劃分出多個線程私人的分配緩衝區。劃分的目的是為了更好地回收記憶體或更快的分配記憶體。

    注意:Java堆可以處在物理上不連續的記憶體空間中,只要邏輯上連續即可。

  (3).虛擬機器棧:它是線程私人的,生命週期與線程相同。三部分組成:局部變數區、運算元棧、幀資料區。(文章後面會詳細介紹)

  (4).本地方法棧:和虛擬機器棧很類似,他們的區別不過是前者為虛擬機器執行Native方法服務,後者為虛擬機器執行Java方法服務。但不同虛擬機器的實現不同,如Sun HotSpot虛擬機器直接就把兩棧合二為一。

  (5).方法區:線程共用的記憶體地區,作用是儲存Java類的結構資訊。當我們建立對象執行個體後,對象的類型資訊儲存在方法區中;執行個體資料存放在堆中;執行個體資料指的是Java中建立的各種執行個體對象以及他們的值,類型資訊指的是定義在Java代碼中的常量、靜態變數以及在類中聲明的各種方法、方法欄位等;同時可能包括即時編譯器編譯後產生的代碼資料。

4.深入理解棧:

  (1).讓我們在來總結一下堆和棧的區別:

    ①.功能不同:棧記憶體用來儲存局部變數和方法調用;而堆用來儲存物件執行個體。

    ②.共用不同:棧是線程私人;而堆是線程共有。

    ③.異常錯誤不同:棧空間不足時為StackOverFlowError;堆空間不足時為OutOfMemoryError。

    ④.空間大小不同:堆遠遠大於棧的記憶體大小。

  (2).我們都知道棧的三部分組成:局部變數區、運算元棧和幀資料區。其中局部變數區和運算元棧要視對應的方法大小而定,是按字長計算的。但調用一個方法時,它從類型資訊中得到此方法局部變數區和運算元棧大小並分配棧記憶體,然後壓入棧中。

    ◆局部變數區:

      是一個以位元組為單位、從0開始計數的數組,類型為short、byte、char的值存入數組前要轉為int值,long和double占連續的倆位元組,但訪問long和double時只需要取出連續的第一項索引即可。(可以理解為方法中局部變數根據類型的不同佔了不同大小的記憶體,並有自己的索引下標,refrence佔一個位元組)                       

    ◆運算元棧:

      同局部變數區一樣,即以位元組為單位的數組。但不同的是它不是通過索引來訪問,而是通過出棧和入棧來訪問。可以把運算元棧理解為儲存計算時的臨時資料的地方。

    ◆幀資料區:

      除了上述兩個部分,Java棧幀還需要一些資料來支援常量池解析、正常方法返回以及異常派發機制。這些資料都儲存在幀資料區中。當JVM執行到需要常量池中的資料時,它會通過幀資料區中指向常量池的指標來訪問它。除此之外,幀資料區中的資料還要處理Java方法的正常結束和異常終止:如果通過return正常結束,當前棧幀彈棧,若有傳回值,則把此值壓入發起調用方法的運算元棧;如果異常中止,幀中儲存了一個對此方法異常參考資料表的引用,有異常時,JVM找catch代碼塊中的代碼,若沒有則方法立即中止,幀中的資訊恢複發起調用的方法的幀,再發起調用方法的上下文重新拋出異常。                                                

5.注意點:

  (1).Java中的基礎資料型別 (Elementary Data Type)不一定儲存在棧中。占記憶體用來儲存局部變數和方法調用,如果該局部變數是基礎資料型別 (Elementary Data Type),則儲存在棧中;如果局部變數是一個對象,則儲存在堆中。

  (2).方法區,有人叫“永久代”,本質不等價,只是因為把GC分代收集擴充至方法。在該地區進行記憶體回收的目的主要是對常量池的回收和類型(記憶體資料)的卸載,但回收效率很低。運行時常量池是方法區的一部分,用來儲存java類檔案常量池中的符號資訊。

  (3).HotSpot方法區的變化:JDK1.2-6,使用永久帶實現方法區,使用GC分代實現方法區;JDK7 Oracle HotSpot 移除永久代,JDK 7 中的符號表被移動到Native Heap中,字串常量池和類引用被移動到Java Heap中;JDK 8 永久代已完全被元空間取代。

Java虛擬機器--Jvm記憶體結構

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.