【JVM Ⅴ】垃圾回收經常使用算法

開始這一章節以前先問本身幾個問題:咱們爲何要學習這一章節?知道了GC 有什麼好處?python

1、前言:


垃圾回收:
在將來的JDK中可能G1會爲ZGC所取代算法

先問本身幾個問題:

  • 什麼是垃圾?
    • 垃圾就是堆內存中(範指)沒有任何指針指向的對象實體。不具備可達性。
  • 爲何要回收垃圾?
    • 由於咱們的內存是有限的,內存長時間不清理就會致使內存溢出,OOM;
    • 只要是程序正在跑,那麼就不斷生成新的對象,咱們須要GC開闢新的空間分配給新的對象。
  • 咱們怎麼回收垃圾?
    • 依靠Java的自動內存回收機制,機制的優劣由算法決定;
    • 或者說是機制的適配度由算法和應用場景共同決定。
  • 何時回收垃圾?
    • 當堆中的實體對象沒有任何指針指向的時候

2、GC的標記階段算法:


標記&清除ide

一、引用計數(Reference Counting):

Java已經擯棄了這種算法,由於此算法須要的額外處理過多工具

【優】效率高,python也在用,就像論文的引用因子同樣,沒有用的文章就應該多多回收,清理學術垃圾。
【缺】沒法處理對象的相互「循環引用」,一旦造成了引用環,就沒有辦法去解決。進而形成內存泄漏。學習

二、可達性分析⭐(根搜索、Tracing Garage Collection):

GC Roots = 起始節點集,從GC Roots開始向下搜索,鏈接的路徑爲引用鏈,GC Roots不可達的對象被判爲不可用。優化

哪些是GC Roots?指針

  • 虛擬棧上的棧幀的局部變量表引用的對象;
  • 方法區上常量引用
  • 方法區上靜態變量
  • 被同步鎖修飾的對象
  • 除了堆區,和堆有聯繫的都是起始節點……

【優】解決了循環引用的缺點
【缺】須要遍歷對象

3、垃圾收集算法:


標記清除算法
複製算法
標記清除整理算法繼承

標記-清除算法:

先mark可達對象,從根節點開始進行線性遍歷。
【優】夠平均
【缺】效率不高,GC的時候致使STW,清楚後存在內存碎片(會存在一個空閒列表)進程

這是最快的清除算法

複製算法

先把空間分爲兩個部分,把標記的對象規整地移到另外一個空間中(指針碰撞的方式)
【優】高效,無需mark/sweep;沒有內存碎片;
【缺】犧牲了大量的空間,」最好大家所有是垃圾!「

標記-清除-整理算法

在標記以後清除完了再進行整理,屬於標記清除算法的優化版,無空閒列表
【優】無空閒列表,無內存碎片;空間開銷低
【缺】時間慢,須要進行屢次操做。

4、finalize&內存分析工具


finalization——免死金牌

finalize是給GC調用的

【問】回收的時候會涉及到哪些操做?會伴隨着什麼狀態?

  • 可觸及:正常狀態,在GC Roots的引用鏈上;
  • 可復活:須要重寫finalize方法纔有的,「皇帝賜給你的重寫finalize方法」
  • 不可觸及:finalize免死金牌只能用一次,若是沒有重寫的finalize方法,那麼就直接掛了。

MAT & GC Roots:

Memory Analyzer Tools 內存分析工具

分析dump文件:根據GC Roots去溯源,監控內存泄漏→ JProfiler

分區算法

將堆空間分紅小空間是爲了下降停頓時間,下降延遲

實際的使用都是複合算法。

String

final是寫死的,不能繼承也不能作任何修改;

Serializable修飾是跨進程

Comparable可比較的

相關文章
相關標籤/搜索