更新時間:2020-09-30 15:32:42 來源:動力節點 瀏覽2121次
事實上,每個Java程序都離不開Java虛擬機,Java程序的運行依靠具體的Java虛擬機實例。JVM在Java的程序運行中起到了關鍵性的作用,JVM內存結構為JVM在Java程序運行中取得了不可忽略的地位。
JVM在Java程序運行時把它所管理的內存劃分為幾個不同的數據區域:程序計數器(Program Counter Register)、虛擬機棧(VM Stack)、本地方法棧(Native Method Stack)、 方法區(Method Area)、堆(Heap)。
JVM內存結構如下圖所示:
如上圖所示,方法區和堆為線程共享區,虛擬機棧、本地方法棧和程序計數器為線程獨占區。方法區則是虛擬機規范中對運行時數據區劃分的一個內存區域,不同的虛擬機廠商可以有不同的實現,而HotSpot虛擬機以永久代來實現方法區,所以方法區是一個規范,而永久代則是其中的一種實現方式。
程序計數器(Program Counter Register),也有稱作為PC寄存器。程序計數器是一塊較小 的空間,它可以看作是當前線程所執行的字節碼的行號指示器。
如果線程執行的是java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址,如果正在執行的是native方法,這個計數器的值為undefined。
JVM的多線程是通過線程輪流切換并分配CPU執行時間片的方式來實現的,任何一個時刻,一個CPU都只會執行一條線程中的指令。為了保證線程切換后能恢復到正確的執行位置,每條線程都需要有一個獨立的程序計數器,各線程間的程序計數器獨立存儲,互不影響。
此區域是唯一一個在java虛擬機規范中沒有規定任何OutOfMemoryError情況的區域,因為程序計數器是由虛擬機內部維護的,不需要開發者進行操作。
描述的是java 方法執行的內存模型:每個方法被執行的時候 都會創建一個“棧幀”用于存儲局部變量表(包括參數)、操作棧、方法出口等信息。每個方法被調用到執行完的過程,就對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。聲明周期與線程相同,是線程私有的。
局部變量表存放了編譯器可知的各種基本數據類型(boolean、byte、char、short、int、float、long、double)、對象引用(引用指針,并非對象本身),其中64位長度的long和double類型的數據會占用2個局部變量的空間,其余數據類型只占1個。局部變量表所需的內存空間在編譯期間完成分配,當進入一個方法時,這個方法需要在棧幀中分配多大的局部變量是完全確定的,在運行期間棧幀不會改變局部變量表的大小空間。
與虛擬機棧基本類似,區別在于虛擬機棧為虛擬機執行的java方法服務,而本地方法棧則是為Native方法服務。HotSpot虛擬機不區分虛擬機棧和本地方法棧,兩者是一塊的。與虛擬機棧一樣,本地方法棧也會拋StackOverflowError和OutOfMemoryError異常。
JVM管理的最大的一塊內存區域,存放著對象的實例,是線程共享區。
堆是垃圾收集器管理的主要區域,因此也被稱為“GC堆”。
JAVA堆的分類:
從內存回收的角度上看,可分為新生代(Eden空間,From Survivor空間、To Survivor空間)及老年代(Tenured Gen)
從內存分配的角度上看,為了解決分配內存時的線程安全性問題,線程共享的JAVA堆中可能劃分出多個線程私有的分配緩沖區(TLAB)
JAVA堆可以處于物理上不連續的內存空間中,只要邏輯上是連續的即可。
可通過參數 -Xmx -Xms 來指定運行時堆內存的大小,堆內存空間不足也會拋OutOfMemoryError異常。
也稱”永久代” 、“非堆”,它用于存儲虛擬機加載的類信息、常量、靜態變量、是各個線程共享的內存區域。默認最小值為16MB,最大值為64MB,可以通過-XX:PermSize 和 -XX:MaxPermSize 參數限制方法區的大小。
運行時常量池:是方法區的一部分,其中的主要內容來自于JVM對Class的加載。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池,用于存放編譯器生成的各種符號引用,這部分內容將在類加載后放到方法區的運行時常量池中。
直接內存并不是虛擬機運行時數據區的一部分,也不是Java虛擬機規范中定義的內存區域,它直接從操作系統中分配,因此不受Java堆大小的限制,但是會受到本機總內存的大小及處理器尋址空間的限制,因此它也可能導致OutOfMemoryError異常出現。在JDK1.4中新引入了NIO機制,它是一種基于通道與緩沖區的新I/O方式,可以直接從操作系統中分配直接內存,即在堆外分配內存,這樣能在一些場景中提高性能,因為避免了在Java堆和Native堆中來回復制數據。
以上就是對JVM內存結構的全面解析,對JVM內存結構的每個部分都作了詳細的介紹,對我們全面學習和了解JVM內存結構會有很大的幫助。當然,你也可以觀看本站的Java零基礎視頻教程,里面有更全面的JVM體系的知識,為你打開一扇Java知識大門!
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習