Java虚拟机JVM常用的几种回收算法和垃圾回收器
1. 垃圾回收算法
1.1 “標記-清除”算法
對內存對象進行可達性分析并標記,標記完成后統一回收。書中說有兩個不足:①標記和清除效率不高;②內存空間是大量不連續的內存碎片。標記是每個回收算法都要經歷的,而且在標記后,清除也是每個算法都要經歷的,只是方式不同,所以我覺得標記和清除效率不高不是“標記-清除”算法的不足,而是每個算法都有,最主要的問題還是內存空間是大量不連續內存碎片。
1.2 “復制”算法
將內存空間分為兩塊,每次只使用其中一塊內存空間。當內存空間滿了,將還存活的對象復制到另一塊內存空間,再將當前內存空間直接清空即可。由于新生代對象生存周期短,所以沒必要1:1分配空間,常用的方式是將內存空間分為一塊Eden和兩塊Survivor區域,之間比例是8:1:1,每次要垃圾回收時,將Eden和其中一個Survivor還存活的內存對象復制到另一塊Survivor內存即可,然后將原先的Eden和Survivor清空即可。如果Survivor存不下要復制的內存對象,那么需要將多余的對象放入老年代,如果多余的對象小于老年代內存空間,那么此次的Minor GC垃圾回收方案是成功的;但如果多余的對象大于老年代內存空間,則要判斷HandlePromotionFailure標志位是否允許分配擔保,如果不允許,那么直接進行Full GC;如果允許,那么判斷老年代剩余的內存空間是否大于歷次進入老年代的內存對象,如果大于,那么會進行一次有風險的Minor GC,如果Minor GC失敗了再進行Full GC。為了避免Full GC,一般允許分配擔保。最主要的問題是對于生存周期長的對象來說,會復制多次,此時效率變低。
1.3 “標記-整理”算法
先標記所有存活的對象,然后讓對象往內存空間一端移動,直接清除邊界外的內存空間。
1.4 “分代”回收算法
年輕代對象生存周期短,那么使用復制算法;而老年代對象生存周期長,使用“標記-清除”或“標記-整理”算法。
2. 垃圾回收器
垃圾回收分為新生代和老年代回收,不同代有不同的回收器,先放一張《深入理解java虛擬機》書中回收器的搭配圖,如下。
2.1 Serial回收器
新生代回收器,使用“復制”回收算法。單線程處理垃圾回收,并在處理垃圾時,暫停所有用戶線程。優點是簡單高效,對于內存空間幾百兆來說,垃圾回收導致用戶線程暫停時間可以控制在幾十毫秒內,對用戶的影響可接受。對應的老年代回收器是Serial Old,“標記-整理”回收算法。
? ? ? ?
在垃圾回收中,并行指有多條垃圾回收線程回收垃圾;而并發指垃圾回收線程和用戶線程一起運行。
2.2 ParNew回收器
多線程版的Serial回收器(并行回收器),也是使用“復制”回收方式。還有一個特點就是它可以和CMS老年代回收器一起搭配使用。
2.3 Parallel Scavenge回收器
也是一個多線程版的“復制”算法回收器(并行回收器),唯一不同的是其它垃圾回收器是盡量縮短用戶線程暫停的時間,而它的關注點是吞吐量,吞吐量=用戶代碼運行時間/(用戶代碼運行時間+垃圾收集時間)。提高吞吐量可以高效利用CPU。可通過控制最大垃圾回收停頓時間-XX:MaxGCPauseMills和吞吐量大小-XX:GCTimeRatio兩個參數控制吞吐量。對應的老年代回收器是Parallel Old,“標記-整理”回收算法。
2.4 Concurrent Mark Sweep(CMS)回收器
多線程的老年代回收器(并行、并發回收器),采用“標記-清除”算法,以最短回收停頓時間為目標。主要有初始標記、并發標記、重新標記以及并發清除四個步驟。初始標記:標記GC Roots能直接關聯的需;并發標記:進行GC Roots跟蹤各個節點的過程;重新標記(并行階段):修正并發標記期間用戶程序更改的那些標記對象;由于最耗時的并發標記和并發清除可以與用戶線程一起工作,所以整體回收使用戶線程暫停的時間很短。缺點:①并發階段會占用一部分CPU資源,導致吞吐量降低;②使用“標記-清除”算法,會有大量的內存碎片存在。③無法處理浮動垃圾,并發清除過程,用戶線程產生的垃圾只能下次清理。
2.5 Garbage-First(G1)回收器
新生代(復制算法)、老年代(標記-整理)一體的回收器。使用G1回收器,堆內存被劃分為多個大小(1~32MB)相等的區域(默認是2048個)。回收步驟:①初始標記;②并發標記;③最終標記;④篩選回收。前三個步驟與CMS一樣,根據用戶期望的GC停頓時間優先回收價值最大(回收所獲得的空間大小以及回收所需時間)的內存區域。優點就是可以根據用戶設定的GC停頓時間來制定區域的垃圾回收列表。
3. 內存分配
3.1 對象優先在新生代的Eden中分配內存
3.2 大對象(長字符串或長數組)直接進入老年代
3.3 長期存活的對象將進入老年代:對象在Eden創建,經過Minor GC并能被Survivor容納,將被移動到Survivor空間中,并且對象年齡設為1;然后再Survivor中每經歷一次Minor GC,年齡就增加一歲,默認增加到15歲晉升到老年代,可通過-xx:MaxTenuringThreshold設置。
3.4 年齡動態判定:如果Survivor空間中相同年齡對象總和大小超過Survivor空間的一半,那么年齡大于或等于該年齡的對象可進入老年代。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Java虚拟机JVM常用的几种回收算法和垃圾回收器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈Java虚拟机JVM的垃圾回收机制
- 下一篇: java美元兑换,(Java实现) 美元