文章目錄
運行時數據區圖示
運行時數據區劃分
方法區
(Method Area)虛擬機棧
(VM Stack)本地方法棧
(Native Method Stack)堆
(Heap)程序計數器
(Program Countor Register)
線程共享
數據區
方法區(Method Area)、堆(Heap)線程隔離
數據區
虛擬機棧(VM Stack)、本地方法棧(Native Method Stack)、程序計數器(Program Countor Register)
方法區(Method Area)
線程共享內存區域,他用於存儲已經被虛擬機加載的類信息、常量、靜態變量、即時編譯之後的代碼數據。雖然java虛擬機的規範把方法區描述爲堆的一個邏輯部分,但是他卻有個別名叫Non-Heap(非堆),目的就是爲了和java堆區分開
- 運行時常量池
運行時常量池是方法區的一部分,Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool Table),用於存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載後進入方法區的運行時常量池中存放
堆(Heap)
是java虛擬機所管轄的最大的一塊內存,java堆是所有線程共享的一塊內存區域,在虛擬機啓動的時候創建。此內存唯一的目的就存放對象實例,幾乎所有的對象實例都在這裏分配內存;從回收的角度來看,java堆細分爲:新生代和老年代
虛擬機棧(VM Stack)
描述的是java方法執行的內存模式,每個方法在執行的同時會創建一個棧楨
(Stack Fream)用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就是對應這一個棧楨在虛擬機棧中的入棧和出棧的過程
- 局部變量表
用於存放編譯時已知的基礎數據類型
(boolean、byte、char、short、folat、double、int、long)、對象引用類型
(reference類型,它不同於對象本身,可能是一個指向對象起始位置的引用指針,也可能是指向一個代表對象的句柄或其他與對象相關的位置)和returnAddress
(指向一條字節碼指令的地址)
本地方法棧(Native Method Stack)
它和虛擬機棧所發揮的作用是一樣的,虛擬機棧是爲虛擬機執行java方法(也就是字節碼)服務的;而本地方法棧是爲虛擬機使用到的Native方法服務的
程序計數器(Program Countor Register)
是一塊較小的內存空間,它可以看做是當前線程所指向的字節碼的行號指示器
直接內存(Direct Memory)
並不是虛擬機運行時數據區的一部分,也不是java虛擬機規範中定義的內存區域。但是這部分內存也被頻繁的使用,而且也可能導致OOM異常,因爲終歸是是使用到了內存。
java在1.4新加入了NIO(New Input/Output)類,引入了通道
(channel)和緩衝區
(Buffer)的I/O方式,他可以通過Native函數庫直接分配堆外內存,然後通過在java堆中保存一個DirectByteBuffer對象作爲這塊內存的引用進行操作;Netty中大量使用到了直接內存來提高讀寫性能;Java 8的HashMap、ConcurrentHashMap等在性能優化上均能找到直接內存操作的影子;但是官方不建議我們在業務代碼中使用直接內存,因爲所有的內存操作都是由程序員去控制,出現問題的可能性大大的提升;因此,unsafe類相關的操作是不允許直接實例化使用,如果需要使用的話,只能通過反射的方式實例化