JVM 探究(一):JVM內存模型概念模型

作為一個 Java 程序員,不了解 Java 內存模型就不能寫出能夠充分利用內存的代碼。本文通過對 Java 內存模型的介紹,讓讀者能夠了解 Java 的內存的分配情況,適合 Java 初學者或者對 JMM 不熟悉的同學。后面的博客會針對每個部分做更加深入的解釋。

Java 內存模型

首先通過下圖對于 Java 內存模型又一個整體的認識,然后針對不同的區域的作用和存儲的內容做進一步的解釋。

Java內存模型

PC(程序計數器)

這里的 PC 不是 Personal Computer,而是 Program Counter Register,從名字就可以看出來,這是一個寄存器,用來存儲需要執行的指令地址。

程序計數器(Program Counter (PC))是在電腦處理器中的一個寄存器,用來指示電腦下一步要運行的指令序列。--WikiPedia

PC 和其他 JVM 內存區域最大的區別是:

“此內存區域是唯一一個在Java虛擬機規范中沒有規定任何OutOfMemoryError情況的區域。
摘錄來自: 周志明. “深入理解Java虛擬機:JVM高級特性與最佳實踐(第2版)”。 iBooks.

像上面的圖片一樣,PC 是每個線程私有的,對于 Java 方法而言,PC 中存儲的是正在執行的虛擬機字節碼的內存地址;對于 Native 方法來說,PC 中的值為空(Undefined)。

Java 虛擬機棧和本地方法棧

虛擬機棧

無論是在大學的 Java 編程課堂上,還是我們在學習過程編碼過程,經常會出現 StackOverFlow,甚至目前最大的技術問答社區的名字也是 StackOverFlow。Java 語言中會產生棧溢出的就是這塊內存區域,當你的程序中設置了超過 JVM 規定的遞歸深度的時候就會觸發這個異常。類似 JMM 的其他內存區域,如果虛擬機棧在動態擴展的時候無法申請到足夠的內存也會報OOM異常。

Java 語言中每一個方法的執行都對應著一個棧幀(Stack Frame)的創建,棧幀中存儲的是局部變量、方法出口等信息,因此對于一個方法的執行而言,所能夠使用到的內存是在編譯期間就能夠完全確定的,在運行期間不會發生變化。在棧幀中,局部變量空間成為 Slot,除了 double 和 long 占有 2 個 slot 外,其他基本數據類型和對象引用都占用 1 個 slot 空間

本地方法棧

本地方法棧和虛擬機棧最大的區別就是虛擬機棧是為執行 Java 字節碼服務的,而本地方法棧是為了虛擬機使用到的 Native 方法服務的。除此之外,Java 虛擬機規范并沒有針對本地方法棧的實現做具體規定。在 HotSpot 虛擬機中,本地方法棧和虛擬機棧是共用同一塊內存的,不做具體區分。同樣,本地方法棧也會產生 OOM 異常和 StackOverFlow 異常。

Java 堆

“The heap is the runtime data area from which memory for all class instances and arrays is allocated。” --Java虛擬機規范

Java 虛擬機規范規定所有的實例對象和數組都應該分配到 Java 堆中。
說的通俗一點就是所有 new 出來的對象和數組都會放到該區域,由于現在的收集器都采用分代收集算法,所以在 Java 堆中又分了新生代和老年代,新生代有做了詳細的區分。該區域的大小可以通過 JVM 參數 -Xmx-Xms 來設置。

直接內存

在 JDK1.4 中引入了 NIO,可以通過 Native 方法直接在堆外分配內存,然后通過在堆中存儲的引用來對這塊內存區域做操作。注意 這塊區域并不會在 -Xmx-Xms 設置的大小之內,因此在設置 JVM 參數的時候要注意考慮這塊內存區域,避免設置的內存區域總額大于物理內存

方法區

Method Area 又叫 NonHeap,也是線程共有的內存區域,用來存:

  • 類信息
  • 常量
  • 靜態變量
  • 字符串常量池

在 JDK1.7 中已經將字符串常量池移出永久代,在 Java8 中更是之內取消了永久代,而是使用了元空間(MetaSpace)來存儲這些信息,從而永久代的大小不需要再制定,只要不超出物理內存的限制就不會產生 OOM 異常

運行時常量池

運行時常量池主要用來存儲累的版本、字段、方法、接口等描述信息。常量池(Constant Pool Table)用來存儲各種字面量和符號引用。String 的 intern() 方法就是在運行期間將對象放到常量池中的。此部分也會出現 OOM 異常。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。