JVM——運行時數據區域

目錄:java

1.概述算法

2.程序計數器數組

3.Java虛擬機棧(棧內存)數據結構

4.本地方法棧函數

5.Java堆優化

6.方法區spa

7.運行時常量池線程

8.直接內存對象

1.概述blog

java虛擬機在執行java程序的過程當中會把它所管理的內存劃分爲若干個不一樣的數據區域。這些區域都有各自的用途,以及建立和銷燬的時間,有的區域隨着虛擬機進程的啓動而存在。有些區域則依賴用戶線程的啓動和結束而創建和銷燬。

java虛擬機所管理的內存將會包括如下幾個運行時數據區域,如圖所示。

2.程序計數器

程序計數器(Program Counter Register)是一塊較小的內存空間。它能夠看作是當前線程所執行的字節碼的行號指示器。

線程私有:爲了線程切換後能恢復到正確的執行位置,每條線程都須要有一個獨立的程序計數器。

若是線程正在執行的是一個java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;若是正在執行的是Native方法,這個計數器值則爲空(Undefined)。

 

3.Java虛擬機棧(棧內存)

java虛擬機棧(Java Virtual Machine Stacks)描述的是java方法執行的內存模型:每一個方法在執行的同時都會建立一個棧幀(Stack Frame)用於存儲局部變量表、操做數棧、動態連接和方法出口等。每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機中從入棧到出棧的過程。

線程私有。

局部變量表存放了編譯器可知的各類基本數據類型、對象引用和returnAddress類型(指向了一條字節碼指令的地址)。

異常:

StackOverflowError異常:若是線程請求的棧深度大於虛擬機所容許的深度。

OutOfMemoryError異常:若是虛擬機棧能夠動態擴展,若是擴展時沒法申請到足夠的內存,就會拋出異常。

 

4.本地方法棧

本地方法棧(Native Method Stack)與虛擬機棧所發揮的做用是很是類似的,他們之間的區別不過是虛擬機棧做爲虛擬機執行java方法服務,而本地方法棧則爲虛擬機使用到的Native方法服務。

在虛擬機規範中對本地方法棧中方法使用的語言,使用方法與數據結構並無強制規定,所以具體的虛擬機能夠自由實現它。

與虛擬機棧同樣,本地方法棧區域也會拋出StackOverflowError異常,OutOfMemoryError異常。

 

5.Java堆

對於大多數應用來講,Java堆(Java Heap)是java虛擬機所管理的內存中最大的一塊。Java堆是被全部線程共享的一塊區域,在虛擬機啓動時建立。

此內存的惟一目的就是存放對象實例。Java虛擬機規範中描述的是:全部的對象實例以及數組都要在堆上分配,可是隨着JIT編譯器的發展與逃逸分析技術逐漸成熟,棧上分配、標量替換優化技術將會致使一些微妙的變化發生,全部的對象在堆上也漸漸變得不是那麼絕對了。

Java堆是垃圾收集器管理的主要區域,所以不少時候已被稱做「GC堆」(Garbage Collection Heap)。

從內存回收的角度來看,因爲如今的收集器基本上都採用分代收集算法,因此java堆還能夠細分爲:新生代和老年代。

從內存分配的角度來看,線程共享的java堆中可能劃分出多個線程私有的分配緩衝區(Thread Local Allocation Buffer,TLAB)。

Java堆能夠處於物理上不連續的內存空間中,只要邏輯上是連續的便可,相似於咱們的磁盤空間。

異常:若是在堆中沒有完成實例分配,而且堆也沒法再擴展時,將會拋出OutOfMemoryError異常。

 

6.方法區

方法區(Method Area)與Java堆同樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。雖然java虛擬機規範把方法區描述爲堆的一個邏輯部分,可是他卻有一個特別的名字叫作Non-Heap(非堆),目的應該是與java堆區分開來。

Java虛擬機規範對方法區的限制分廠寬鬆,除了和Java堆同樣不須要連續的內存和能夠選擇固定大小或者可擴展外,還能夠選擇不實現垃圾收集。相對而言,垃圾收集行爲在這個區域師表較少出現的,但並不是數據進入了方法區就如永久代的名字同樣「永久」存在了。這個區域內存回收目標主要是針對常量池的回收和對類型的卸載。

 

7.運行時常量池

運行時常量池(Runtime Constant Pool)是方法區的一部分。class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool Table),用於存放編譯器生成的各類字面量和符號引用,這部份內容將在類加載後進入方法區的運行時常量池中存放。

 

8.直接內存

直接內存(Direct Memory)並非虛擬機運行時數據區的一部分,也不是java虛擬機規範中定義的內存區域。可是這部份內存也被頻繁的使用,並且也可能致使OutOfMemoryError異常出現。

在jdk1.4中新加入了NIO(New Input/Output)類引入了一種或基於通道(Channel)與緩衝區(buffer)的I/O方式,它可使用Native函數庫直接分配堆外內存,而後經過一個存儲在Java堆中的DirectByteBuffer對象做爲這塊內存的引用進行操做。

相關文章
相關標籤/搜索