聊一下JVM是如何進行垃圾回收的演算法
導讀 | 我們聊一下JVM是如何進行回收的。 |
顧名思義,其過程分為兩個階段,分別是 標記和 清除。首先標記出所有需要回收的物件,然後統一對標記的物件進行回收。這個演算法的十分的侷限,首先標記和清除的兩個過程效率都不高,而且這樣的清理方式會產生大量的記憶體碎片,什麼意思呢?
就是雖然總體看起來還有足夠的剩餘記憶體空間,但是他們都是以一塊很小的記憶體分散在各個地方。如果此時需要為一個大物件申請空間,即使總體上的記憶體空間足夠,但是JVM無法找到一塊這麼大的連續記憶體空間,就會導致觸發一次GC。
其大致的思路是,將現有的記憶體空間分為兩半A和B,所有的新物件的記憶體都在A中分配,然後當A用完了之後,就開始物件存活判斷,將A中還存活的物件複製到B去,然後一次性將A中的記憶體空間回收掉。
這樣一來就不會出現使用
標記-清除所造成的記憶體碎片的問題了。但是,它仍然有自己的不足。那就是以記憶體空間縮小了一半為代價,而在某些情況下,這種代價其實是很高的。
堆中新生代就是採用的複製演算法。剛剛提到過,新生代被分為了Eden、From Survivor、To Survivor,由於幾乎所有的新物件都會在這裡分配記憶體,所以Eden區比Survivor區要大很多。因此Eden區和Survivor區就不需要按照複製演算法預設的1:1的來分配記憶體。
在HotSpot中Eden和Survivor的比例預設是8:1,也就意味著只有10%的空間會被浪費掉。
看到這你可能會發現一個問題。
既然你的Eden區要比Survivor區大這麼多,要是一次GC之後的存活物件的大小
大於Survivor區的總大小該怎麼處理?
的確,在新生代GC時,最壞的情況就是Eden區的所有物件都是存活的,那這個JVM會怎麼處理呢?這裡需要引入一個概念叫做
記憶體分配擔保。
當發生了上面這種情況,新生代需要老年代的記憶體空間來做擔保,把Survivor存放不下的物件直接存進老年代中。
標記-整理其GC的過程與標記-清楚是一樣的,只不過會讓所有的存活物件往同一邊移動,這樣一來就不會像標記-整理那樣留下大量的記憶體碎片。
這也是當前主流虛擬機器所採用的演算法,其實就是針對不同的記憶體區域的特性,使用上面提到過的不同的演算法。
例如新生代的特性是大部分的物件都是需要被回收掉的,只有少量物件會存活下來。所以新生代一般都是採用 複製演算法。
而老年代屬於物件存活率都很高的記憶體空間,則採用 標記-清除和 標記-整理演算法來進行垃圾回收。
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2783049/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JVM 垃圾回收演算法和垃圾回收器JVM演算法
- JVM垃圾回收演算法JVM演算法
- JVM系列(五) - JVM垃圾回收演算法JVM演算法
- JVM(九):垃圾回收演算法JVM演算法
- JVM垃圾回收JVM
- jvm - 垃圾回收JVM
- [JVM]垃圾回收JVM
- jvm有哪些垃圾回收演算法JVM演算法
- jvm垃圾分代回收演算法JVM演算法
- 到底是誰在回收 JVM 的垃圾JVM
- jvm(三)——jvm垃圾回收演算法以及實現JVM演算法
- 【JVM】垃圾回收的四大演算法JVM演算法
- JVM 中的垃圾回收JVM
- JVM調優:基本垃圾回收演算法JVM演算法
- JVM垃圾回收概述JVM
- JVM垃圾回收(下)JVM
- JVM - 垃圾回收概述JVM
- JVM垃圾回收器JVM
- JVM(四)垃圾回收的實現演算法和執行細節JVM演算法
- jvm的垃圾回收機制JVM
- 關於JVM的垃圾回收JVM
- JVM之垃圾回收(1-概述+演算法)JVM演算法
- 深入理解JVM(四)——垃圾回收演算法JVM演算法
- [效能][JVM]jvm垃圾回收機制JVM
- JVM系列(六) – JVM垃圾回收器JVM
- JVM系列(六) - JVM垃圾回收器JVM
- 【JVM】JVM系列之垃圾回收(二)JVM
- JVM垃圾回收歷險JVM
- JVM 垃圾回收機制JVM
- 淺談JVM垃圾回收JVM
- JVM-垃圾回收篇JVM
- JVM垃圾回收機制JVM
- JVM垃圾回收詳解JVM
- jvm 自動垃圾回收JVM
- Java教程分享:JVM垃圾回收機制之物件回收演算法JavaJVM物件演算法
- javascript 垃圾回收演算法瞭解一下JavaScript演算法
- 更快的JVM垃圾回收器:ShenandoahJVMNaN
- JVM調優之垃圾定位、垃圾回收演算法、垃圾處理器對比JVM演算法