之前的java垃圾回收之標記清除算法詳解 會導致內存碎片。下文的介紹的coping算法可以解決內存碎片問題。
概述
如果jvm使用了coping算法,一開始就會將可用內存分為兩塊,from域和to域, 每次只是使用from域,to域則空閑著。當from域內存不夠了,開始執行gc操作,這個時候,會把from域存活的對象拷貝到to域,然后直接把from域進行內存清理。
應用場景
coping算法一般是使用在新生代中,因為新生代中的對象一般都是朝生夕死的,存活對象的數量并不多,這樣使用coping算法進行拷貝時效率比較高。
jvm將heap 內存劃分為新生代與老年代,又將新生代劃分為eden(伊甸園) 與2塊survivor space(幸存者區) ,然后在eden –>survivor space 以及from survivor space 與to survivor space 之間實行copying 算法。
不過jvm在應用coping算法時,并不是把內存按照1:1來劃分的,這樣太浪費內存空間了。一般的jvm都是8:1。也即是說,eden區:from區:to區域的比例是8:1:1
始終有90%的空間是可以用來創建對象的,而剩下的10%用來存放回收后存活的對象。
1、當eden區滿的時候,會觸發第一次young gc,把還活著的對象拷貝到survivor from區;當eden區再次觸發young gc的時候,會掃描eden區和from區域,對兩個區域進行垃圾回收,經過這次回收后還存活的對象,則直接復制到to區域,并將eden和from區域清空。
2、當后續eden又發生young gc的時候,會對eden和to區域進行垃圾回收,存活的對象復制到from區域,并將eden和to區域清空。
3、可見部分對象會在from和to區域中復制來復制去,如此交換15次(由jvm參數maxtenuringthreshold決定,這個參數默認是15),最終如果還是存活,就存入到老年代
注意:
- 萬一存活對象數量比較多,那么to域的內存可能不夠存放,這個時候會借助老年代的空間。
優點
在存活對象不多的情況下,性能高,能解決內存碎片和java垃圾回收之標記清除算法詳解 中導致的引用更新問題。
缺點
- 會造成一部分的內存浪費。不過可以根據實際情況,將內存塊大小比例適當調整;
- 如果存活對象的數量比較大,coping的性能會變得很差。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。如果你想了解更多相關內容請查看下面相關鏈接
原文鏈接:https://blog.csdn.net/linsongbin1/article/details/51668859