java內存區域劃分詳解

十一期間很簡單的介紹了一下java虛擬機的基本內容,沒有很詳細的介紹,想了解以前內容的,能夠看看從公衆號歷史信息自行查找下,今天本身又回來寫了一篇,有什麼問題歡迎糾正。java

概述:這篇將從概念上介紹Java虛擬機內存的各個區域,講解這些區域的做用,服務對象以及其中可能產生的問題。
     Java虛擬機在執行Java程序的過程當中會把它所管理的內存劃分爲若干個不一樣的數據區域,這些區域都有各自的用途以及建立和銷燬時間,稱之爲運行時數據區域。

    運行時數據區主要有程序計數器,Java虛擬機棧,本地方法棧,Java堆,方法區,運行時常量池等部分組成。
數組

    針對上面的圖文,下面開始開始進入各個部分的詳細內容了。微信

      程序計數器,線程私有,因爲Java虛擬機的多線程是經過線程流轉切換並分配處理器執行時間的方式來實現的,在任意一個肯定的時間點,一個處理器都只會執行一條線程中的指令。所以,爲了線程切換後能恢復到正確的執行位置,每條線程都須要有一個獨立的程序計數器,即程序計數器是線程私有的。若是線程正在執行的是一個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;若線程正在執行的是Native方法,這個計數器的值通常就是undefined。多線程

       程序計數器可能出現的異常:此內存區域是惟一一個在Java虛擬機規範中沒有規定任何OutofMemory區域的地方,通常遇到OOM問題,不會是這裏。函數

      Java虛擬機棧,一樣是線程私有的,Java虛擬機棧描述的是Java方法執行的,每一個方法在執行的同時都會建立一個棧幀用於存儲局部變量表,操做數棧,動態連接,方法出口等信息。每個方法從調用直至完成的過程,就對應着一個棧幀在虛擬機棧中入棧和出棧的過程。
性能

      局部變量表存放了編譯期可知的各類數據類型,對象引用和返回地址類型,而且它所須要的內存空間在編譯期完成分配,在方法運行期間不會改變局部變量表的大小。
spa

  這部分區域可能出現的異常,線程請求的棧深度大於虛擬機所容許的深度,出現StackOverflowError錯誤,若虛擬機棧能夠動態擴展,但在擴展的過程當中,沒法申請申請到足夠的內存會出現OutOfMemoryError錯誤。
下面咱們繼續說本地方法棧吧,一樣也是線程私有的,這篇文章略長,須要一些耐心,本地方法棧和虛擬機棧的做用相似,區別也只是虛擬機棧爲虛擬機執行Java方法服務,本地方法棧則爲虛擬機執行Native方法服務。Sun Hotspot直接將本地方法棧和虛擬機棧合二爲一。 好了,咱們說下,這部分區域可能出現的異常 S tack OverError ,OutOfMemoryError 錯誤

     ok,咱們繼續吧,下面要說的就是最最最最重要的了,Java堆,Java堆屬於線程共享的區域,全部的對象實例和數組都要在堆上進行分配,Java堆在虛擬機啓動時建立,此內存的惟一目的就是存放對象實例,Java堆能夠處於物理上不連續的內存空間,只要邏輯上是連續的便可。.net

    在這塊區域內,可能出現的異常,當在堆中沒有內存能夠完成實例對象的分配時,堆也沒法再擴展時,會出現OutOfMemoryError錯誤信息。線程

     下面說下方法區吧,方法區也是線程共享的,方法區用於存儲虛擬機加載的類信息,常量,靜態變量,及時編譯器JIT編譯後的代碼等數據,這塊區域的內存回收目標主要是針對常量池的回收和對類型的卸載。可能出現的異常,當方法區沒法知足內存分配需求時,也一樣會出現OutOfMemroyError錯誤信息。翻譯

     運行時常量池是方法區的一部分。Class文件中除了有類的版本,字段,方法,接口等描述信息外,還有一項就是常量池,用於存放編譯期生成的各類字面量和符號引用,這部份內容將在類加載後進入方法區的運行時常量池中存放。通常來講,除了保存Class文件中的符號引用外,還會把翻譯出來的直接引用也存儲在運行時常量池中。運行時常量池相對於Class文件常量池的另一個重要特徵是具有動態性,即運行期間也可能將新的常量放入池中,String類的itern()方法,此區域可能出現的異常,當常量池沒法再申請到內存時會跑出OutOfMemoryError錯誤。

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

 直接內存的分配不會受到Java堆大小的限制,可是,既然是內存,確定會受到本機總內存大小和處理器尋址空間的限制。

   在這說明一下,以上說的內容會有一點和jdk8不太同樣,由於jdk8多了元空間的概念,本身沒有在這裏進行說下,說的虛擬機針對於主流的虛擬機hotSpot,ok接着十一那篇文章,這篇文章也詳細介紹了每一個區域都是幹啥的,都會出現什麼異常,時間也不早了,寫一篇文章,從構思到書寫,花費的時間確實很長,感謝你的閱讀,喜歡這篇文章的能夠分享一下,喜歡的能夠關注一下,ok,這篇文章就到這結束了。來源java相關書籍。


本文分享自微信公衆號 - WwpwW(gh_245290c1861a)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索