GC常見的算法

1.GC (Garbage Collection)
java garbage collection is an automatic process to manage the runtime memory used by programs.by doing it automatic JVM relieves the programer of the overhead of assigning and freeing up memory resources in a program.
垃圾回收機制是由垃圾回收器Garbage Collection來實現的。GC是後臺的守護進程,它的特別之處是它是一個低優先級進程。但是可以根據內存的使用情況動態的調整他的優先級,因此,它是內存中低到一定程度時,纔會自動運行,從而實現對內存的回收,這就是垃圾回收的時間不確定的原因。這個服務不是我們啓動的是自動啓動的。
程序運行期間,所有對象實例存儲在運行時數據區域的heap中,當一個對象不再被引用(使用),他就需要被回收,在GC過程中,這些不需要被使用的對象從heap中回收,這樣就會有空間循環被利用。
2. 引用計數法
簡單但是速度很慢,缺陷是不能處理循環引用的情況。 
原理:此對象有一個引用,既增加一個計數器,刪除一個引用減少一個計數器,垃圾回收時,只回收計數器爲0的對象,此算法最致命的是無法處理循環引用的情況。

3.標記-清除算法
標記清除算法分爲“標記”和“清除”兩個階段:首先標記出所有需要回收的對象,在標記完成後統一回收所有被標記的對象。

之所以說他是最基礎的收集算法,是因爲後續的收集算法都是基於這種思路並且對其不足進行改進而得到的。

它的主要不足有兩個: 
1. 一個是效率問題,標記和清除兩個過程的效率都不高 
2. 另一個是空間問題,標記清除後會產生大量不連續的內存碎片,空間碎片太多可能會導致以後再程序運行過程中需要分配較大對象時,無法找到足夠的連續的內存而不得不提前觸發另一次垃圾收集動作。

4.複製算法
爲了解決效率問題,一種稱爲“複製”(Copying)的收集算法出現了,它將可用的內存按照容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用完了,就將活着的對象複製到另外一塊上面,然後再把已使用過的內存空間一次清理掉。這樣使得每次都是對整個半區進行內存回收,內存分配時也就不用考慮內存碎片等複雜情況。只要移動堆指針,按照順序分配內存即可,實現簡單,運行高效。只是這種算法的代價是將內存縮小爲原來的一半。

5. 標記-整理算法
複製收集算法在對象存活率較高的時候,就要進行較多的複製操作,效率將會變低。更關鍵的是,如果不想浪費50%的空間,就需要額外的空間進行分配擔保,以應對被使用的內存中所有對象都是100%存活的極端情況,所以在老年代一般不能直接選用這種算法。根據老年代的特點。有人提出了另外一種“標記-整理”(Mark-Compact)算法,標記過程仍然與”標記-清除”算法一樣,但是後續步驟不是直接對可回收對象進行清理,而是讓所有存活的對象都向一端移動,然後直接清理掉端邊界意外的內存。

6.分代收集算法
這種算法並沒有什麼新的思路,只是根據對象的存活週期的不同,將內存劃分爲幾塊。一般是把java堆分成新生代和老年代,這樣就可以根絕各個年代的特點採取最適當的收集算法。在新生代中,每次垃圾回收時都發現大批對象的死去,只有少量存活,那就選用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。而老年代中因爲對象存活率高,沒有額外空間對它進行分配擔保,就必須使用”標記-清理”或者“標記-整理”算法來進行回收。

7.系統線程劃分
串行收集器

使用單線程處理所有垃圾回收工作,因爲無需多線程交互,所以效率比較高。但是,也無法使用多處理器的優勢。所以此收集器適合單處理器的機器。當然,此收集器也可以用在小數量(100M左右)情況下的多處理器機器上,可以使用-XX:+UseSerialGC打開。

並行收集器

對年輕代進行並行垃圾回收,因此可以減少垃圾回收的時間,一般在多線程多處理器上使用,使用-XX:+UseParallelGC打開。年老代進行並行收集。如果年老代不使用併發收集的話,是使用單線程進行垃圾回收,因此會制約擴展能力,使用-XX:+UseParallelOldGC打開。

使用-XX:ParallelGCThreads=設置並行垃圾回收的線程數,此值可以設置與機器處理數量相等。 
此收集器可以進行如下配置: 
最大垃圾回收暫停:指定垃圾回收時的最大暫停時間,通過-XX:MaxGCPauseMillis=指定。爲毫秒數,如果指定了這個值的話,堆大小和垃圾回收相關參數會進行調整以達到指定值。此值可能會減少應用的吞吐量。吞吐量:吞吐量爲垃圾回收時間與非垃圾回收時間的比值。通過-XX:GCTimeRatio=來設定,公式爲1/(1+N),例如,-XX:GCTimeRatio=19時,表示5%的時間用於垃圾回收,默認情況爲99,既1%的時間用於垃圾回收。

併發收集器

可以保證大部分工作都併發執行(應用不停止),垃圾回收只暫停很少的時間,此收集器適合對響應時間要求比較高的中,大型應用,使用-XX:+UseConcMarkSweepGC打開。

併發收集器主要減少年老代的暫停時間,他在應用不停止的情況下使用獨立的垃圾回收線程,跟蹤可達對象,在每個年老代垃圾回收週期中,在收集初期併發收集器會對整個應用進行簡短的暫停,在收集中還會再暫停一次,第二次暫停會比第一次長,在此過程中多個線程同時進行垃圾回收工作。

併發收集器使用處理器換來短暫的停頓時間,在一個N個處理器的系統上,併發收集部分使用K/N個可用處理器進行回收,一般情況下1<=K<=N/4

在只有一個處理器的主機上使用併發收集器,設置爲incremental mode模式也可以獲得較短的停頓時間。

浮動垃圾:由於在應用運行的同時進行垃圾回收,所以有些垃圾回收可能在垃圾回收完成時產生,這樣就造成了“floating Garbage”,這些垃圾需要在下次垃圾回收週期時才能回收掉,所以併發收集器一般需要20%的預留空間用於這些浮動垃圾。

Concurrent Mode Failure:併發收集器在應用程序運行時進行收集,所以需要保證堆在垃圾回收的這段時間有足夠的空間供程序使用,否則,垃圾回收還未完成,堆空間先充滿了,這種情況下將會發生“併發模式失敗”,此時整個應用將會暫停。進行垃圾回收。

啓動併發收集器:因爲併發收集在應用運行時進行收集,睡衣必須保證收集完成之前有足夠的內存空間供程序使用,否則會出現“Concurrent Mode Failure”,通過設置-XX:CMSinitiatingOccupancyFraction=指定還有多少剩餘堆時開始執行併發收集。

並行:多個事件同一時間發生,同時做多件事 
併發:多個事件在同一個時間間隔內發生。每年11.11日狂歡節,一天內接受的最大人數。

8.小結

————————————————
版權聲明:本文爲CSDN博主「九師兄-樑川川」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_21383435/article/details/80473540

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章