天天看點

JVM垃圾回收與記憶體配置設定

JVM垃圾回收與記憶體配置設定

垃圾回收判斷算法:

1. 引用計數法

給對象添加一個計數器,當引用時計數器就加1,如果引用失效時,則計數器則減1。如果計數器為0時,則表示該對象不被引用。進而判定可以回收。

2. 可達性分析算法

GCROOTS為起點,向下搜尋,搜尋過程的路徑作為引用鍊,當一個對象沒有任何一個引用鍊,則表明對象不可被引用。
GCRoot的對象:

2.1 虛拟機棧中引用的對象

2.2 方法區中的類靜态屬性引用對象

2.3 方法區中常量引用對象

2.4 本地方法棧中JNI引用的對象

引用:

引用可以分為:強引用、軟引用、弱引用、虛引用
						強引用:一定不會被回收的對象、發生洩露的主要原因是不可回收對象
						軟引用:如果下次GC時,記憶體不夠才回收、記憶體夠則不回收
						弱引用:在下次GC時一定會被回收。
						虛引用:跟蹤對象被垃圾回收的狀态。
           

垃圾回收的特殊情況

若被系統标記為回收的對象,在GC之前調用了finalize()。則可以逃脫一次GC。如果調用之後,仍然被标記,那麼下次一定被回收。也就是說finalize()方法隻能實作一次。

垃圾回收算法

1.标記-清除算法

首先要标記回收的對象,标記完成之後統一回收。在垃圾回收時會産生大量的碎片

2.标記-整理算法

首先标記回收的對象,标記完成後,将存存活的對象移動到另一端,然後清除掉端界以外的對象。

3.複制算法

将記憶體分為兩塊區域,每次隻用其中的一塊,當一塊記憶體用完時,會将存活的對象移動到另一塊記憶體中,一般用來回收新生代。

HotShot算法的實作

1.枚舉根節點:可達性分析算法從GCROOTS節點中尋找引用鍊,此時整個虛拟機都需要停止工作,因為防止引用鍊不停的變化。CMS收集器需要stw。目前主流的虛拟機都是準确式GC。實作的方法都是OopMap。在jit編譯期,OopMap會在特定的位置記錄下引用的位置。

2.安全點:在枚舉時,OopMap會記錄下引用位置的安全點,隻要到安全點才能暫停,此時一般分為搶先式中斷和主動式中斷。搶先式中斷在GC時,會把所有線程都中斷,讓沒有在安全點的線程恢複跑到安全點。主動式中斷,如果發現線程自己所經過的點為安全點,就會停止線程等待檢測。

3.安全區:安全區域就在一段代碼中,引用不會發生變化。如需要檢測,則會等待檢測,如果檢測完畢後方可離開安全區域。

垃圾回收步驟

如果采用可達性分析算法,JVM虛拟機會在目前程式設定GCROOTS節點,此時會向下搜尋,其中會由OopMap幫助在安全點進行标記引用,然後在安全區進行檢測。如果有引用失效的情況,則會進行垃圾收集。在不同的區域中,采用不同的收集器。

垃圾收集器

1.Serial收集器:隻使用一個CPU的收集器,在垃圾收集時會中斷其他工作線程,優點是簡單高效,依然是Client預設下的新生代收集器。

2.parnew 收集器:是Serial收集器的多線程版本。隻有該收集器可以和CMS收集器配合,是一款并發收集器。

3.parnew scavenge 收集器: 是新生代收集器,采用的是複制算法,主要控制吞吐量

4.Serial Old收集器,是Serial收集器的老年代版本。單線程收集器,可以和parnew scavenge收集器共用。

5.parnew old 收集器,是parnew 收集器的老年代版本,吞吐量優先。

6.CMS收集器,吞吐量優先的收集器,響應時間端。用于B/S系統的服務端,采用标記-清除的算法。共有4個階段。分别為:初始标記、并發标記、重新标記、并發清除。其中初始标記和重新标記需要stw。初始标記時間較短,隻是GCRORTS關聯一下對象。重新标記是修正并發标記期間因使用者程式繼續運作而導緻的變動。耗時時間較長的是并發标記和并發清除。但是會随着使用者一起工作。缺點是:标記-清除算法。會産生大量的記憶體碎片。還會産生浮動垃圾,主要是因為并發标記産生的。

7.G1收集器:面向服務端的垃圾回收器。并行與并發、分代收集、空間整合、可預測停頓。執行步驟為、初始标記、并發标記、最終回收、篩選回收。

記憶體配置設定與回收政策

1.優先配置設定到Eden區,沒有足夠的空間會發生minor gc,此時from survivor 會移動到to survivor

2.如果新生代gc完成後,記憶體還不夠則大對象會直接配置設定到老年代,主要是記憶體擔保機制。此外長期存活的對象也會進入到老年代。系統預設為新對象的年齡為1,當經曆過一次gc,年齡則會加1,當年齡增加到15時,則會移入到老年代。

3.在新生代發生的gc 為minor gc,老年代發生的gc 為major gc 。而full gc則表明同時發生在老年代和新生代。

回收機制

首先記憶體配置設定到Eden區中 ,如果Eden區的記憶體不夠則會發生minor gc,此時存活的對象會從from survivor移動到to survivor區,eden區的對象也會移入并發生垃圾回收。這樣不會産生記憶體碎片。當to survivor區記憶體滿時,發生gc 會将記憶體移入到另一個survivor區,并發生垃圾回收,如果經曆了15次gc 則會移動到老年代。新生代預設采用的serial收集器。或者采用parnew scavenge收集器。如果接着記憶體配置設定,長期存活的對象會移入到老年代中。如果老年代記憶體不足時,則會發生full gc。目前來說,垃圾回收都是分代收集的。采用cms收集器。因為響應時間短。并且為并發的操作。cms和parnew收集器共同工作。