淺析JVM內存區域及垃圾回收

1、JVM簡介java

JVM,全稱Java Virtual Machine,即Java虛擬機。以Java做爲編程語言所編寫的應用程序都是運行在JVM上的。JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是經過在實際的計算機上仿真模擬各類計算機功能來實現的。Java有個很是重要的特色就是與平臺的無關性,而JVM正是實現這一特色的關鍵。算法

JVM對程序的執行主要分爲兩個步驟,第一步是編譯,即將.java的源文件編譯成爲.class的字節碼文件,第二步是解釋,JVM對字節碼文件進行解釋執行。兩個步驟流程圖分別以下兩圖所示:編程

 

 

 

2、JVM內存區域數組

JVM整個大系統又分爲兩個子系統。第一個是ClassLoader,即類加載器,功能是將編寫的類加載到JVM中。第二個是Execution Engine,即執行引擎,負責對編譯後的字節碼文件進行解釋執行。上述中Execution Engine又分爲兩部分,第一部分是Runtime data area,即運行時數據區域,即至關於JVM中的內存,第二部分是Native interface,即本地化接口,主要用於執行其餘非Java編程語言編寫的程序。編程語言

重點就是前者Runtime data area,它分爲五個部分,分別是Method area(方法區),Heap(堆),VM stack(虛擬機棧),Program counter  register(程序計數器),Native method stack(本地方法棧)。前二者線程共享,後三者線程隔離。以下圖所示:spa

歸納地說,JVM初始運行的時候都會分配好Method area(方法區)和Heap(堆),而JVM 每遇到一個線程,就爲其分配Program counter  register(程序計數器)、VM stack(虛擬機棧)、Native method stack(本地方法棧), 當線程終止時,三者(虛擬機棧,本地方法棧和程序計數器)所佔用的內存空間也會被釋放掉。這也是爲何把數據區域分爲線程共享和線程隔離的緣由,線程隔離的那三個區域的生命週期與所屬線程相同,而線程共享的區域與Java程序運行的生命週期相同,因此這也是系統垃圾回收場所只發生在線程共享的區域(實際上對大部分虛擬機來講是發生在Heap上)的緣由。關於內存溢出異常以下圖所示:操作系統

 

一、Method area(方法區)線程

方法區包括常量池與靜態域。存放了所加載類的信息(名稱、修飾符等)、類的靜態變量、類的常量、類的Field信息、類的方法信息。當開發人員在程序中經過Class對象中的getName、isInterface等方法來獲取信息時,這些數據都來源於方法區。對象

二、Heap(堆)blog

堆是JVM所管理的內存中最大的一塊,幾乎全部的對象實例和數組都在此區域,能夠認爲Java中全部經過new建立的對象的內存都在此分配,堆中的對象的內存須要等待GC進行回收。

三、Program counter  register(程序計數器)

程序計數器是一塊較小的內存空間,它是當前線程所執行的字節碼的行號指示器,字節碼解釋器工做時經過改變該計數器的值來選擇下一條須要執行的字節碼指令,分支、跳轉、循環等基礎功能都要依賴它來實現。

四、VM stack(虛擬機棧)

虛擬機棧描述的是Java方法執行的內存模型,每一個方法在執行時都會建立一個棧幀(Stack Frame),棧幀用於存儲局部變量表(基本數據類型、對象的引用等)、操做數棧、動態連接、方法返回地址和一些額外的附加信息。

五、Native method stack(本地方法棧)

該區域與虛擬機棧所發揮的做用很是類似,只是虛擬機棧爲虛擬機執行Java方法服務,而本地方法棧則爲使用到的本地操做系統(Native)方法服務。

 

 

3、JVM垃圾回收

JVM的GenerationalCollecting(垃圾回收)原理是把對象分爲年青代(Young)、年老代(Tenured)、持久代(Perm),對不一樣生命週期的對象使用不一樣的算法。

一般JVM內存回收老是指Heap(堆)內存回收,確實只有Heap(堆)中的內容是動態申請分配的,因此以上對象的年輕代和年老代都是指的JVM的Heap(堆)空間,而持久代則是以前提到的Method area(方法區),不屬於Heap(堆)。

1. 年輕代

Java應用在分配Java對象時,這些對象會被分配到年輕代堆空間中去

這個空間大可能是小對象而且會被頻繁回收

因爲年輕代堆空間的垃圾回收會很頻繁,所以其垃圾回收算法會更加劇視回收效率

2. 年老代

年輕代堆空間的長期存活對象會轉移到(也許是永久性轉移)年老代堆空間

這個堆空間一般比年輕代的堆空間大,而且其空間增加速度較緩

因爲大部分JVM堆空間都分配給了年老代,所以其垃圾回收算法須要更節省空間,此算法須要可以處理低垃圾密度的堆空間

3. 持久代

存放VM和Java類的元數據(metadata),以及interned字符串和類的靜態變量

 

當這三個分代的堆空間比較緊張或者沒有足夠的空間來爲新到的請求分配的時候,垃圾回收機制就會起做用。有兩種類型的垃圾回收方式:次收集(Minor GC)和全收集(Full GC)。當年輕代堆空間滿了的時候,會觸發次收集將還存活的對象移到年老代堆空間。當年老代堆空間滿了的時候,會觸發一個覆蓋全範圍的對象堆的全收集。

 

 

 

 

至此是關於淺析JVM內存區域及垃圾回收,僅供參考。

若有疏漏錯誤之處,還請不吝賜教!

相關文章
相關標籤/搜索