1. 程式人生 > >深入理解JAVA虛擬機器2:JVM記憶體結構

深入理解JAVA虛擬機器2:JVM記憶體結構

記憶體結構一覽

在上一篇文章中,我們最後給出了一幅圖

這幅圖中,就包含了JVM的記憶體結構的所有組成元素,他們分別是:java堆記憶體、java棧、方法區、本地方法區以及pc暫存器,接下來我們就對這些區域逐一介紹。

java堆

      Java堆是Java虛擬機器所管理的記憶體中最大的一塊。是執行緒共享的一塊記憶體區域,在虛擬機器啟動時建立。此記憶體區域的唯一目的就是存放物件例項,幾乎所有的物件例項都在這裡分配記憶體。

       Java堆是垃圾收集器管理的主要區域,因此很多時候也被稱做“GC堆”。如果從記憶體回收的角度看,由於現在收集器基本都是採用的分代收集演算法,所以Java堆中還可以細分為:新生代和老年代;再細緻一點的有(伊甸區)Eden空間、(倖存者區)From Survivor空間、To Survivor空間等。

       根據Java虛擬機器規範的規定,Java堆可以處於物理上不連續的記憶體空間中,只要邏輯上是連續的即可,就像我們的磁碟空間一樣。在實現時,既可以實現成固定大小的,也可以是可擴充套件的,不過當前主流的虛擬機器都是按照可擴充套件來實現的(通過-Xmx和-Xms控制)。

如果在堆中沒有記憶體完成例項分配,並且堆也無法再擴充套件時,將會丟擲OutOfMemoryError異常。

java棧

      棧是每個執行緒私有的區域,它的生命週期與執行緒相同,一個執行緒對應一個java棧,每執行一個方法就會往棧中壓入一個元素,這個元素叫“棧幀”,而棧幀中包括了方法中的區域性變數、用於存放中間狀態值的操作棧,這裡面有很多細節,我們以後再講。如果java棧空間不足了,程式會丟擲StackOverflowError異常,想一想什麼情況下會容易產生這個錯誤,對,遞迴,遞迴如果深度很深,就會執行大量的方法,方法越多java棧的佔用空間越大。

方法區(也叫做持久區)

      方法區(Method Area)與Java堆一樣,是各個執行緒共享的記憶體區域,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的程式碼等資料。

本地方法區

      本地方法棧角色和java棧類似,其區別不過是虛擬機器棧為虛擬機器執行Java方法(也就是位元組碼)服務,而它是為虛擬機器使用到的native方法服務,本地方法棧存放的方法呼叫本地方法介面,最終呼叫本地方法庫,實現與作業系統、硬體互動的目的。

程式計數器

       當我們的類載入完畢的時候,例項物件、方法、靜態變數都去了自己改去的地方,那麼問題來了,程式該怎麼執行,哪個方法先執行,哪個方法後執行,這些指令執行的順序就是PC暫存器在管,它的作用就是控制程式指令的執行順序。如果執行緒正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機器位元組碼指令的地址;如果正在執行的是Natvie方法,這個計數器值則為空(Undefined)。此記憶體區域是唯一一個在Java虛擬機器規範中沒有規定任何OutOfMemoryError情況的區域。

總結

     上文對JVM記憶體結構進行了個簡單的介紹,並對對其組成元素逐一進行了介紹,讓我們對JVM記憶體結構有了更加全面的認識。