標籤:缺點 line 執行個體 計數 先來 複製演算法 script markdown 其他
ps:文中的圖片都來自網路。部分圖片來源
1. 前言
作為一種進階語言,比起c和c++來,很進步的一點就是記憶體回收機制。這省去來了我們很多的工作,不過,我們仍然需要瞭解記憶體回收,這對我們的成長很有協助。
2. 引用計數法
引用計數法在很多進階語言都有,如python,java也不例外。對象內部維護有一個被其他對象引用的引用計數,當這個引用計數為0的時候,表示對象可以被回收。
引用計數法存在一個問題,就是循環參考,加入a引用b,b同時也引用a,那麼就存在ab的引用計數都不為0的情況。
3. 可達性分析演算法
ps:圖片來自網路
我們可以很明顯的看出,一個對象的根節點,不是gc root的話,就可以被回收。
4. 參考型別
java中有四種參考型別,預設是強參考型別:(下面都是說引用還在的情況下)
- 強引用 寧願crash,也不回收
- 弱引用 記憶體不夠用,就回收
- 軟引用 記憶體回收行程,掃描到 就回收
- 虛引用 隨時回收
5. 回收方法區(永久代)
主要回收兩部分內容:廢棄常亮和無用的類
- 廢棄常量 沒有被引用時,就會被清楚
- 無用的類,要滿足一下三個條件
- 所有的類執行個體都被回收
- 該類的classloader 被回收
- 該類對應的class對象沒有在任何地方被引用,也沒有通過反射訪問類的方法
6. 垃圾收集演算法
6.1 標記-清除
首先標記需要回收的對象,然後清除需要回收的對象。
缺點:
- 標記 清除兩個過程效率都不高
- 存在大量的記憶體片段
6.2 複製演算法
將記憶體分為兩塊,每次都使用其中一塊,當這一塊用完了,就將存活的對象複製到另一塊,然後清除可以被回收的對象。
6.3 標記-整理
先標記可以被回收的對象,然後,讓存活的對象向一端移動,最後直接清理掉另一端的記憶體。
6.4 分代收集演算法
將記憶體根據生命週期分為幾種,一般為新生代和老生代,然後根據特性,選擇不同的回收演算法。
7. 記憶體配置
先來兩個GC的概念:
新生代GC Minor GC
指發生在新生代的垃圾收集動作,因為java對象大多具備自生夕滅的特徵,所以minor gc非常頻繁,回收速度也比較快
老生代GC Major GC/Full GC
指老生代gc,出現了major gc,經常會伴隨至少一次minor gc,major gc的速度一般會比minor gc慢10倍以上
- 對象優先在新生代eden區分配
- 長期存活的對象直接進入老生代,當對象度過一次minor gc,歲數+1,當過了一定值的時候,就進入老生代,
- 動態對象年齡判斷,如果survivor中相同年齡的對象的大小達到總大小的一半,年齡大於或等於這個年齡的對象直接進入老生代
- 空間分配擔保
深入理解java虛擬機器筆記(二)-記憶體回收