這篇文章帶給大家的內容是關於JVM記憶體區域和垃圾回收的分析(圖文),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
一、JVM簡介
JVM,全名為Java Virtual Machine,即Java虛擬機器。以Java作為程式語言所寫的應用程式都是在JVM上運行的。 JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是透過在實際的計算機上模擬模擬各種計算機功能來實現的。 Java有個非常重要的特點就是與平台的無關性,而JVM正是實現這項特點的關鍵。
JVM對程式的執行主要分為兩個步驟,第一步是編譯,即將.java的源文件編譯成為.class的字節碼文件,第二步是解釋,JVM對字節碼文件進行解釋執行。兩個步驟流程圖分別如下兩張圖:
#
二、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(本地方法堆疊)。前兩者線程共享,後三者線程隔離。如下圖所示:
概括地說,JVM初始運行的時候都會分配好Method area(方法區)和Heap(堆),而JVM 每遇到一個線程,就為其分配Program counter register(程式計數器)、VM stack(虛擬機棧)、Native method stack(本地方法棧), 當線程終止時,三者(虛擬機棧,本地方法堆疊和程式計數器)所佔用的記憶體空間也會被釋放掉。這也是為什麼把資料區域分成執行緒共享和執行緒隔離的原因,執行緒隔離的那三個區域的生命週期與所屬執行緒相同,而執行緒共享的區域與Java程式運行的生命週期相同,所以這也是系統垃圾回收場所只發生在線程共享的區域(實際上對大部分虛擬機器來說是發生在Heap上)的原因。關於記憶體溢出例外情況如下圖:
1、Method area(方法區)
方法區包括常數池與靜態域。存放了所載入類別的資訊(名稱、修飾符等)、類別的靜態變數、類別的常數、類別的Field資訊、類別的方法資訊。當開發人員在程式中透過Class物件中的getName、isInterface等方法來取得資訊時,這些資料都來自方法區。
2、Heap(堆)
堆是JVM所管理的記憶體中最大的一塊,幾乎所有的物件實例和陣列都在此區域,可以認為Java中所有透過new創建的物件的記憶體都在此分配,堆中的物件的記憶體需要等待GC進行回收。
3、Program counter register(程式計數器)
程式計數器是一塊較小的記憶體空間,它是目前執行緒所執行的字節碼的行號指示器,字節碼解釋器工作時透過改變該計數器的值來選擇下一條需要執行的字節碼指令,分支、跳躍、循環等基礎功能都要依賴它來實現。
4、VM stack(虛擬機器堆疊)
虛擬機器堆疊描述的是Java方法執行的記憶體模型,每個方法在執行時都會建立一個堆疊幀(Stack Frame),堆疊幀用於儲存局部變數表(基本資料型別、物件的參考等)、操作數棧、動態連結、方法傳回位址和一些額外的附加資訊。
5、Native method stack(本地方法堆疊)
該區域與虛擬機器堆疊所發揮的作用非常相似,只是虛擬機器堆疊為虛擬機器執行Java方法服務,而本地方法棧則為使用到的本機作業系統(Native)方法服務。
三、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記憶體區域及垃圾回收,僅供參考。
#以上是JVM記憶體區域與垃圾回收的分析(圖文)的詳細內容。更多資訊請關注PHP中文網其他相關文章!