JVM 運行時數據區詳解

1、運行時數據區

  Java虛擬機在執行Java程序的過程當中會把它所管理的內存劃分爲若干個不一樣數據區域。html

    1.有一些是隨虛擬機的啓動而建立,隨虛擬機的退出而銷燬,全部的線程共享這些數據區。java

    2.第二種則是與線程一一對應,隨線程的開始和結束而建立和銷燬,線程之間相互隔離。程序員

  Java虛擬機所管理的內存將會包括如下幾個運行時數據區域jvm

    

2、數據區詳解

1.程序計數器(Program Counter Register)函數

  • 也叫PC寄存器是一塊較小的內存空間,它的做用是存儲當前線程所執行的字節碼的信號指示器。
  • 每一條JVM線程都有本身的PC寄存器。
  • 在任意時刻,一條JVM線程只會執行一個方法的代碼。該方法稱爲該線程的當前方法(Current Method)。
  • 若是該方法是java方法,那PC寄存器保存JVM正在執行的字節碼指令的地址。
  • 若是該方法是native,那PC寄存器的值是undefined。
  • 此內存區域是惟一一個在Java虛擬機規範中沒有規定任何OutOfMemoryError狀況的區域。

2.Java虛擬機棧(Java Virtual Machine Stack)spa

  • 每個JVM線程都有本身的java虛擬機棧,這個棧與線程同時建立,它的生命週期與線程相同。
  • 用於存儲局部變量、操做棧、動態連接、方法出口
  • 虛擬機棧描述的是Java方法執行的內存模型:
    • 每一個方法被執行的時候都會同時建立一個棧幀(Stack Frame)用於存儲局部變量表、操做數棧、動態連接、方法出口等信息。
    • 每個方法被調用直至執行完成的過程就對應着一個棧幀在虛擬機棧中從入棧到出棧的過程。
    • 局部變量表存放了編譯器剋制的各類基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(Object reference)和字節碼指令地址(returnAddress類型)。
  • JVM stack 能夠被實現成固定大小,也能夠根據計算動態擴展。
    • 若是採用固定大小的JVM stack設計,那麼每條線程的JVM Stack容量應該在線程建立時獨立地選定。
    • JVM實現應該提供調節JVM Stack初始容量的手段。
    • 若是採用動態擴展和收縮的JVM Stack方式,應該提供調節最大、最小容量的手段。
  • 對於32位的jvm,默認大小爲256kb, 而64位的jvm, 默認大小爲512kb,能夠經過-Xss設置虛擬機棧的最大值。不過若是設置過大,會影響到可建立的線程數量。
  • JVM Stack 異常狀況:
    • StackOverflowError:當線程請求分配的棧容量超過JVM容許的最大容量時拋出.
    • OutOfMemoryError:若是JVM Stack能夠動態擴展,可是在嘗試擴展時沒法申請到足夠的內存去完成擴展,或者在創建新的線程時沒有足夠的內存去建立對應的虛擬機棧時拋出。

3.本地方法棧(Native Method Stack)線程

  • Java虛擬機可能會使用到傳統的棧來支持native方法(使用Java語言之外的其它語言編寫的方法)的執行,這個棧就是本地方法棧.
    • 若是JVM不支持native方法,也不依賴與傳統方法棧的話,能夠無需支持本地方法棧。
    • 若是支持本地方法棧,則這個棧通常會在線程建立的時候按線程分配。
  • 異常狀況:
    • StackOverflowError:若是線程請求分配的棧容量超過本地方法棧容許的最大容量時拋出.
    • OutOfMemoryError:若是本地方法棧能夠動態擴展,而且擴展的動做已經嘗試過,可是目前沒法申請到足夠的內存去完成擴展,或者在創建新的線程時沒有足夠的內存去建立對應的本地方法棧,那Java虛擬機將會拋出一個OutOfMemoryError異常。

注:以上三個數據區屬於各個線程單享的,每一個線程建立時都會建立此三個數據區。各個線程之間相互隔離,互不影響。設計

4.方法區(Method Area)htm

  • 方法區是可供各條線程共享的運行時內存區域。存儲了每個類的結構信息,例如:運行時常量池(Runtime Constant Pool)、字段和方法數據、構造函數和普通方法的字節碼內容、還包括一些在類、實例、接口初始化時用到的特殊方法。
  • 方法區在虛擬機啓動的時候建立。
  • 方法區的容量能夠是固定大小的,也能夠隨着程序執行的需求動態擴展,並在不須要過多空間時自動收縮。
  • 方法區在實際內存空間中能夠是不連續的。
  • Java虛擬機實現應當提供給程序員或者最終用戶調節方法區初始容量的手段,對於能夠動態擴展和收縮方法區來講,則應當提供調節其最大、最小容量的手段。
  • Java 方法區異常:
    • OutOfMemoryError: 若是方法區的內存空間不能知足內存分配請求,那Java虛擬機將拋出一個OutOfMemoryError異常。

運行時常量池(Runtime Constant Pool對象

  • 運行時常量池是每個類或接口的常量池(Constant_Pool)的運行時表現形式,它包括了若干種常量:編譯器可知的數值字面量到必須運行期解析後才能得到的方法或字段的引用。
  • 運行時常量池是方法區的一部分。每個運行時常量池都分配在JVM的方法區中,在類和接口被加載到JVM後,對應的運行時常量池就被建立。
  • 在建立類和接口的運行時常量池時,可能會遇到的異常:
    • OutOfMemoryError:建立類和接口時,若構造運行時常量池所需的內存空間超過了方法區所能提供的最大內存空間後時拋出.

5.Java堆(Heap)

  • 在JVM中,堆是可供各條線程共享的運行時內存區域,也是供全部類實例和數據對象分配內存的區域。
  • Java堆是Java虛擬機所管理的內存中最大的一塊。
  • 經過-Xms和-Xmx來控制初始堆大小和最大堆大小
  • Java堆載虛擬機啓動的時候就被建立,堆中儲存了各類對象,這些對象被自動管理內存系統(Automatic Storage Management System,也便是常說的「Garbage Collector(垃圾回收器)」)所管理。這些對象無需、也沒法顯示地被銷燬。
  • Java堆的容量能夠是固定大小,也能夠隨着需求動態擴展,並在不須要過多空間時自動收縮。
  • Java堆所使用的內存不須要保證是物理連續的,只要邏輯上是連續的便可。
  • JVM實現應當提供給程序員調節Java 堆初始容量的手段,對於可動態擴展和收縮的堆來講,則應當提供調節其最大和最小容量的手段。
  • Java 堆異常:
    • OutOfMemoryError:若是實際所需的堆超過了自動內存管理系統能提供的最大容量時拋出。

參考原文:http://chenzhou123520.iteye.com/blog/1585224

     http://www.open-open.com/lib/view/open1383745340321.html

相關文章
相關標籤/搜索