JVM概念與內存區域

JVM

概念

JVM即java虛擬機,是可運行java代碼的假想計算機,包括一套字節碼指令集、一組寄存器、一個棧、一個垃圾回收,堆和一個存儲方法域。JVM是運行在操做系統之上的,它與硬件沒有直接的交互。java

JVM內存區域

JVM有5大內存區域,分別是方法區,虛擬機棧,本地方法區,堆,程序計數器。
image.png緩存

程序計數器

程序計數器是一塊較小的內存空間,能夠看做是當前線程所執行的字節碼的行號指示器。在Java虛擬機的概念模型裏,字節碼解釋器的功能就是經過改變這個計數器的值來選取下一條須要執行的字節碼指令,它是程序控制流的指示器,分支,循環,跳轉,異常處理,線程恢復等基礎功能都須要依賴這個計數器來完成。
JAVA虛擬機的多線程是經過線程輪流切換,分配處理器執行的時間的方式來實現的,即在任何一個肯定時刻,一個處理器中只有一個線程在執行。所以爲了保證每次線程切換以後可以恢復到正確的執行位置,每條線程都須要有一個獨立的程序計數器,各條程序之間的計數器互不影響,獨立存儲,這類內存區域被稱爲「線程私有」的內存。
程序計數器是Java虛擬機中惟一個不會出現OutOfMemoryErroe情況的內存區域。多線程

Java虛擬機棧

虛擬機棧與程序計數器同樣也是線程私有的,生命週期與線程相同。虛擬機棧描述的是Java虛擬機的線程內存模型:每一個方法被執行的時候都會建立一個棧幀用於存儲局部變量表,操做數棧,動態鏈接,方法出口等信息。每個方法從調用到執行完畢的過程,就對應着一個棧幀在虛擬機棧中從入棧到棧的過程。
線程請求的深度大於虛擬機所容許的深度,將會拋出StackOverflowError異常,若是虛擬機棧容量能夠動態拓展,那麼當拓展到沒法請求到足夠的內存時會拋出OutOfMemoryErroe異常。spa

本地方法棧

本地方法棧與虛擬機棧所發揮的做用是很是類似的,區別是虛擬機棧爲虛擬機執行Java方法服務,而本地方法棧則是爲虛擬機使用到的本地方法服務。
與虛擬機同樣本地方法棧也會在棧深度溢出或者棧拓展失敗時分別拋出StackOverflowErrorOutOfMemoryErroe異常。操作系統

Java堆

Java堆是虛擬機所管理的內存中的最大的一塊。Java堆是被全部線程所共享的一塊內存區域,在虛擬機被啓動的時候建立。此內存區域的惟一目的就是存放實例對象,Java世界裏「幾乎」全部對象的實例都在這裏分配內存。
Java堆的內存既能夠被實現成固定大小的也能夠是拓展的,當前主流的Java虛擬機都是按照可拓展來實現的。若是Java堆中沒有內存完成實例分配,而且堆也沒法再拓展時,則會拋出OutOfMemoryErroe異常。線程

方法區

方法區與Java堆同樣,也是各個線程共享的內存區域。用於存儲被虛擬機加載的類型信息,常量,靜態變量,即時編譯器編譯後的代碼緩存等數據。
若是方法區沒法知足新的內存分配需求時,將拋出OutOfMemoryErroe異常。對象

運行時的常量池

運行時的常量池也是方法區的一部分。Class文件中除了有類的版本,字段,方法,接口等描述信息外。還有一項信息是常量池表,用於存放編譯期生成的各類字面量與符號引用,這部份內容將在類加載後存放到方法區的運行時常量池中。
常量池沒法申請到內存時會拋出OutOfMemoryErroe異常。blog

總結

程序計數器是惟一不會拋出OutOfMemoryErroe異常的。
程序計數器與Java虛擬機棧,本地方法區都是線程私有的。接口