歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> JVM中的垃圾回收

JVM中的垃圾回收

日期:2017/3/1 9:18:22   编辑:Linux編程

一、垃圾回收的概念

Java中的內存回收即Jvm運行時的內存的回收,需要回收的區域有方法區和Java堆。由於程序計數器,Java虛擬機棧和本地方法棧在方法結束或者是線程結束時會自動進行回收所以無須考慮回收。為什麼需要垃圾回收呢?因為電腦中的內存的大小是有限而固定的,在運行過程中由於類的加載和創建,內存中已使用的內存會越來越大,導致後來的程序執行時無法進行分配內存進行執行,此時就需要進行垃圾回收,將已經使用的內存區域中沒有在使用的數據清除,從而使後來的程序能夠正常運行。

二、如何判斷一個對象可以進行回收?

在進行垃圾回收的時候,如何判斷一個對象是否已經可以進行回收了呢?一個對象可以進行回收的時候就是不再有變量引用這個對象。常規去判斷一個對象是否還有變量引用,使用的是引用計數法。就是給對象添加一個引用計數器,如果一個變量引用了這個對象,就把計數器裡面的值加一,引用失效時就減一。進行垃圾回收的時候,對計數器裡面的值為零的對象進行回收。但是主流的Java虛擬機並沒有采用此種方法進行垃圾回收,而是采用GC Roots可達性算法進行判斷一個對象是否可以進行回收。

采用GC Roots可達性算法進行判斷對象是否回收時,就是通過一系列可以作為GC Roots的對象作為起始點,向下搜索對象,形成多條對象可以GC Roots對象的路徑,稱為引用鏈,當一個對象不存在這個引用鏈中時,就可以進行回收。

圖中的對象A、B、C、D都存在路徑(引用鏈)到達GC Roots對象,F則不存在,所以進行內存回收會回收對象F,而不會回收對象A,B,C,D。

三、垃圾回收算法

Jvm中的內存回收使用以下幾種回收算法:

1.標記-清除算法:在進行垃圾回收的時候,將不再引用的對象進行標記,標記完成後,統一對於標記的對象進行回收。

未回收時:

進行標記-清除時,會對未引用對象進行全部標記,在標記完成後,對標記的未引用對象的內存進行回收。

標記-清除後:

2.標記-整理算法:在進行垃圾回收的時候,將不再引用的對象進行標記,標記完成後,統一對於標記的對象進行回收後,對內存進行整理,將引用對象移動到一起

標記-整理之前:

如同標記-清除方法一樣,會對未引用對象進行標記,標記完成後進行清除,然後將還在引用對象的內存移動到一起

標記整理後:   

3.復制算法::將內存劃分成相等的兩塊內存,每次只使用其中一塊內存進行分配,當正在使用內存中的空間使用完畢時,將使用的內存中的還存活的對象復制到另一塊未使用的內存上,然後將清理已使用內存的空間。

回收之前:

復制算法回收之後:

4.分代算法:將回收區分為新生代和老年代,新生代采用復制算法,老年代采用標記-清除或者是標記-整理算法

四、垃圾收集器

垃圾收集器就是垃圾回收算法的具體實現。Jvm中存在一下幾種垃圾收集器

1.Serial收集器:使用單線程對於垃圾進行回收,進行垃圾回收時必須停掉所有得工作進程進行垃圾回收,使用標記-整理算法。

2..Serial Old收集器:Serial收集器的老年代版本。

3.ParNew收集器:Seria收集器的多線程版本。

4.Parallel Scavenge收集器:采用復制算法的收集器,控制吞吐量進行垃圾收集的算法,吞吐量即CPU運行用戶代碼的時間與CPU運行總時間的比值,用戶可以通過設置吞吐量來控制垃圾回收的效率。

5.Parallel Old收集器:Parallel Scavenge的老年代版本,采用標記整理算法和使用多線程回收。

6.CMS收集器:以獲得最短回收停頓時間為目標的收集器,采用標記-清除算法。回收的流程為:初始標記->並發標記->重新標記->並發清除.

7.G1收集器:最新的收集器,回收流程為:初始標記->並發標記->最終標記->篩選回收。 

Copyright © Linux教程網 All Rights Reserved