1、垃圾收集(garbage collection,gc),需要考慮以下3件事
(1)哪些記憶體需要**?(what)
(2)什麼時候**?(when)
(3)如何**?(how)
2、判斷堆記憶體是否需要**,主要是判斷物件的引用是否還存在,主要有以下策略
(1)引用計數演算法:每個物件含有乙個引用計數器,有引用+1,引用失效則-1,任意時刻計數器為0則判定物件不會再被使用,演算法優點是實現簡單,執行效率高,缺點是無法解決物件之間迴圈引用造成的問題。
(2)可達性分析演算法:以gc roots為起點向下搜尋,當乙個物件和gc roots之間沒有任何可達路徑時,即判定該物件是不可用的。
主流j**a虛擬機器均採用可達性分析演算法來管理記憶體。
(3)j**a中可以作為gc roots的物件有:虛擬機器棧(棧幀中的區域性變數表)中引用的物件、方法區中靜態類屬性引用的物件、方法區中常量引用的物件以及本地方法棧中jni(即native方法)引用的物件。
(4)判斷乙個物件是否存活,至少要經歷兩次標記過程:
第一次經過可達性分析後發現沒有與gc roots相連線的引用鏈,將進行第一次標記並且進行一次篩選,篩選的條件是此物件是否有必要執行finalize()方法(任何乙個物件的finalize()方法只會被系統自動呼叫一次)。
當物件被判定為有必要執行finalize()方法,將會被放置在乙個叫做f-queue的佇列之中,gc將會對f-queue中的物件進行第二次小規模的標記,finalize()方法是物件避免被**的最後一次機會,如果物件在finalize()方法中重新建立了引用關係,則第二次標記時它將被移除「即將**」的集合,否則就會被gc**掉。
3、物件引用的分類自jdk1.2以後分為以下幾種
(1)強引用:new物件
(2)軟引用:softreference
(3)弱引用:weakreference
(4)虛引用:phantomreference
4、常見垃圾收集演算法
(1)標記-清除演算法(老年代)
(2)複製演算法(新生代)
(3)標記-整理演算法(老年代)
(4)分代收集演算法(新生代和老年代)
5、hotspot的gc演算法實現
(1)列舉根節點(gc roots):主要在全域性性的引用(常量或靜態屬性)與執行上下文(棧幀中的本地變數表)中,進行時必須停頓所有的j**a執行執行緒(stop the world),搜尋引用鏈是使用一組稱為oopmap的資料結構來實現的。
(2)安全點(safepoint):如果為每一條指令都生成對應的oopmap,將會需要大量的額外空間,所以只在特定的位置(如方法呼叫、迴圈跳轉、異常跳轉等)進行gc,即程式執行時並非在所有地方都停頓下來進行gc,只有在到達安全點時才能暫停。執行緒執行時通過主動式中斷,即輪詢安全點設定的中斷標誌來中斷當前任務從而在安全點停頓下來進行gc。
(3)安全區域(safe region):當執行緒處於sleep或者blocked狀態,無法響應jvm的中斷請求時,這是就需要通過安全區域來判斷是否進行gc,即在一段**中,引用關係不會發生變化,在這個區域內的任意地方開始gc都是安全的,可以看做被擴充套件了的安全點。
6、垃圾收集器
(1)cms
(2)g1
7、記憶體分配與**策略
(1)大多數情況下,物件在新生代eden區中分配,當eden區沒有足夠空間進行分配時,虛擬機器將發生一次minor gc。由於大多數物件都是朝生夕死,所以minor gc的發生會非常頻繁,速度也比較快。
(2)大物件(如長字串和陣列)或者長期存活的物件(物件年齡判斷)分配在老年代,老年代為新生代提供空間分配擔保,當老年代空間不足時會發生一次full gc,
速度一般會比minor gc慢10倍以上。
8、hotspot虛擬機器將新生代分為乙個eden區和兩個survivor區,預設eden和survivor的比例大小是8:1,即新生代可分配的記憶體大小為總記憶體大小的90%(乙個eden區+乙個survivor區)。
JVM 垃圾收集
1.引用計算法 給物件新增乙個引用計數器,每當有乙個地方引用它時,計數器值加一,當引用失效時,計數器值減一。當該物件的計數器值為0時,表明該物件不可用,虛擬機器可以對其進行 但是不能解決迴圈引用問題。2.可達性分析演算法 演算法思想為 以一系列的gc roots作為起點進行搜尋,搜尋走過的路徑稱之為...
JVM 垃圾收集演算法
這裡只是各個演算法的思想及發展過程 這是最基礎的收集演算法,分為兩個過程,標記和清除兩個階段。首先標記出需要 的物件,在標記完成後統一 掉所有被標記的物件。標記的過程就是之前判定物件的時候標記的。後續的演算法都是基於這種思路進行改進的。缺點呢,有兩個,1.效率問題,標記和清除的效率都不高。2.空間問...
JVM之垃圾收集演算法
標記清除演算法主要分為兩個階段,標記階段和清除階段,這兩個階段效率比較低,而且收集之後會產生記憶體碎片,無法為大的物件分配記憶體空間。如下圖 複製演算法解決了記憶體碎片問題,但是隨之而來的卻是把記憶體一分為二。原理是 記憶體一分為二,每次使用其中的一半,當需要 的時候,講死亡物件清理,然後存活物件移...