JVM運行時數據區(二)

四、本地方法棧算法

  本地方法棧與虛擬機棧所發揮的做用是很是類似的,它們之間的區別不過是虛擬機棧爲虛擬機執行Java方法服務,而本地方法棧則爲虛擬機使用到的Native方法服務。數組

  與Java虛擬機棧同樣本地方法區也會拋出StackOverflowError和OutOfMemoryError異常。函數

五、Java堆性能

  Java堆是Java虛擬機所管理的內存中最大的一塊,Java堆是被全部線程共享的一塊內存區域,在虛擬機啓動時建立。該內存區域存在的惟一目的就是存放對象的實例,幾乎全部的對象和數組(static關鍵字、Native關鍵字所修飾的方法除外)的實例都在Java堆中進行內存分配。線程

  Java堆是垃圾收集管理的主要區域,因爲如今的垃圾收集器基本都採用分代收集算法,因此Java堆能夠分爲:新生代和老年代;再細緻一點能夠將新生代分爲Eden區、Survivor區域(Survivor能夠分爲兩個大小相同的區域分別爲From Survivor和To Survivor,且兩個區域能夠進行角色互換)。絕大多數狀況下,對象首先分配在Eden區,在一次新生代回收後(YGC),若是對象還存活,則會進入s0或者s1區(即From Survivor或者To Survivor區),以後通過若干次的垃圾回收以後,若是對象一直沒有被回收,生存得足夠長,該對象就會被移入老年代。對象

  根據Java虛擬機規範的規定,Java堆能夠處於物理上不連續的內存空間中,只要邏輯上是連續的便可,就像磁盤空間同樣。Java堆的容量可使固定的,也能夠隨着程序執行的需求動態擴展,並在不須要過多空間時自動收縮(能夠經過-Xmx和-Xms來進行Java堆大小的控制)。若是實際所需的堆超過了自動內存管理系統提供的最大容量,那麼Java虛擬機將會拋出OOM異常。接口

六、方法區內存

  在Java虛擬機中,方法區是JVM內存區域很是重要的一塊內存區域,與Java堆相似,方法區是各個線程共享的內存區域,它存儲了每個類的結構信息,例如,運行時常量池、字段、方法數據、構造函數和普通方法的字節碼內容,還包括一些在類、實例、接口初始化時用到的特殊方法。虛擬機

  方法區在虛擬機啓動的時候建立,雖然方法區是堆的邏輯組成部分,可是簡單的虛擬機實現能夠選擇在這個區域不實現垃圾收集與壓縮(Java虛擬機規範),可是該區域卻有一個別名叫作Non-Heap(非堆),目的應該是與Java堆區分開來。方法區的容量能夠是固定的,也能夠隨着程序執行的需求動態擴展,並在不須要過多空間時自動收縮。方法區在實際內存中能夠是不連續的。能夠經過-XX:PermSize和-XX:MaxPermSize來控制持久代大小。若是方法區的內存空間不能知足內存分配請求,那麼Java虛擬機將會拋出一個OOM異常。內存管理

七、運行時常量池

  運行時常量池是方法區的一部分。class文件中每個類或接口的常量池表的運行時表現形式,包括了若干種不一樣的常量,從編譯期可知的數值字面量到必須在運行期解析後才能得到的方法或字段引用。當建立類或接口時,若是構造運行時常量池所須要的內存空間超過了方法區所能提供的最大值,那麼Java虛擬機將會拋出OOM異常。

八、直接內存

  直接內存並非Java虛擬機運行時數據區的一部分,也不是Java虛擬機規範中定義的內存區域。在JDK1.4中新加入了NIO類,引入了一種基於通道與緩衝區的IO方式,它可使用Native函數庫直接分配堆外內存,而後經過一個存儲在Java堆中的DirectByteBuffer對象做爲這塊內存的引用進行操做,這樣能在一些場景中顯著提升性能,由於避免了在Java堆和Native堆中來回複製數據。

  本機的直接內存的分配不會受到Java堆大小的限制,既然是內存,確定仍是受到本機總內存大小以及處理器尋址空間的限制。在實際工做中該區域也會存在OOM異常。

相關文章
相關標籤/搜索