淺談JVM垃圾回收有哪些常用算法
一、前言:
垃圾回收:
在未來的JDK中可能G1會為ZGC所取代
先問自己幾個問題:
什麼是垃圾?
- 垃圾就是堆內存中(范指)沒有任何指針指向的對象實體。不具有可達性。
為什麼要回收垃圾?
- 因為我們的內存是有限的,內存長時間不清理就會導致內存溢出,OOM;
- 隻要是程序正在跑,那麼就不斷生成新的對象,我們需要GC開辟新的空間分配給新的對象。
我們怎麼回收垃圾?
- 依靠Java的自動內存回收機制,機制的優劣由算法決定;
- 或者說是機制的適配度由算法和應用場景共同決定。
什麼時候回收垃圾?
- 當堆中的實體對象沒有任何指針指向的時候
二、GC的標記階段算法:
標記&清除
1、引用計數(Reference Counting):
Java已經擯棄瞭這種算法,因為此算法需要的額外處理過多
【優】效率高,python也在用,就像論文的引用因子一樣,沒有用的文章就應該多多回收,清理學術垃圾。
【缺】無法處理對象的相互“循環引用”,一旦形成瞭引用環,就沒有辦法去解決。進而造成內存泄漏。
2、可達性分析⭐(根搜索、Tracing Garage Collection):
GC Roots = 起始節點集,從GC Roots開始向下搜索,連接的路徑為引用鏈,GC Roots不可達的對象被判為不可用。
哪些是GC Roots?
- 虛擬棧上的棧幀的局部變量表引用的對象;
- 方法區上常量引用
- 方法區上靜態變量
- 被同步鎖修飾的對象
- 除瞭堆區,和堆有聯系的都是起始節點……
【優】解決瞭循環引用的缺點
【缺】需要遍歷
三、垃圾收集算法:
標記清除算法
復制算法
標記清除整理算法
標記-清除算法:
先mark可達對象,從根節點開始進行線性遍歷。
【優】夠平均
【缺】效率不高,GC的時候導致STW,清楚後存在內存碎片(會存在一個空閑列表)
這是最快的清除算法
復制算法
先把空間分為兩個部分,把標記的對象規整地移到另一個空間中(指針碰撞的方式)
【優】高效,無需mark/sweep;沒有內存碎片;
【缺】犧牲瞭大量的空間,”最好你們全部是垃圾!“
標記-清除-整理算法
在標記之後清除完瞭再進行整理,屬於標記清除算法的優化版,無空閑列表
【優】無空閑列表,無內存碎片;空間開銷低
【缺】時間慢,需要進行多次操作。
四、finalize&內存分析工具
finalization——免死金牌
finalize是給GC調用的
【問】回收的時候會涉及到哪些操作?會伴隨著什麼狀態?
- 可觸及:正常狀態,在GC Roots的引用鏈上;
- 可復活:需要重寫finalize方法才有的,“皇帝賜給你的重寫finalize方法”
- 不可觸及:finalize免死金牌隻能用一次,如果沒有重寫的finalize方法,那麼就直接掛瞭。
MAT & GC Roots:
Memory Analyzer Tools 內存分析工具
分析dump文件:根據GC Roots去溯源,監控內存泄漏→ JProfiler
分區算法
將堆空間分成小空間是為瞭降低停頓時間,降低延遲
實際的使用都是復合算法。
String
final是寫死的,不能繼承也不能做任何修改;
Serializable修飾是跨進程
Comparable可比較的
到此這篇關於淺談JVM垃圾回收有哪些常用算法的文章就介紹到這瞭,更多相關JVM垃圾回收算法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!