1. 哪些內存需要回收?
堆,方法
程序計數器,虛擬機棧,本地方法棧3個區域隨線程而生,隨線程而滅,內存的回收具有確定性
2. 回收哪些對象?
引用計數法:給對象添加一個引用計數器,每當有一個地方引用它時,計數器就增1,引用失效,減一 (循環引用的問題)
可達性分析算法:通過一系列的稱爲“GC Roots”的對象作爲起點,從這些節點開始向下搜索,搜索走過的路徑稱爲引引用鏈,當一個對象到GC Roots沒有任何引用鏈相連時,該對象是不可用的,極爲氪回收對象。
2.1.引用分類
強引用(Strong Reference):類似 “Object obj = new Object()”,只要強引用存在,垃圾收集器永遠不會回收掉被引用的對象。
軟引用(Strong Reference):當垃圾蒐集器工作時,如果當前內存夠,就不回收,反之回收
弱引用(Strong Reference):只要垃圾蒐集器工作,就會被回收。被關聯的對象只能生存到下一次垃圾收集發生前。
虛引用(Strong Reference):不能通過虛引用指向一個對象實例。唯一目的是在關聯對象被回收的時候收到一個系統通知,一般和ReferenceQueue聯合使用。
2.2. 對象死亡過程
真正判定一個對象死亡,要經歷兩次標記過程。
2.3 回收方法區(HotSpot虛擬機中的永久代)
回收內容:廢棄常量和無用的類
3.垃圾回收算法
3.1標記-清除算法
過程:標記出需要回收的對象,在標記完成後統一回收被標記的對象,
缺點:效率低,內存碎片
3.2複製算法 適用於存活率較低的時候
將內存分爲大小相等的兩塊,每次只使用其中一塊。當這一塊的內存用完了就將還存活的對象複製到另外一塊上面,然後再把已使用過的內存空間一次清理掉。
3.3標記-整理算法 適用於存活率較高的時候
標記出需要回收的對象,在標記後,將所有存貨的對象都向一端移動,然後直接清理掉端邊界以外的內存
3.4 分代收集算法
根據對象存活週期的不同將內存劃分爲幾塊,再根據各年代的特點採用最適當的收集算法。
在新生代中,對象存活率較低,可以採用複製算法
在老生代中,對象的存活率較高,可以採用標記-清除或者標記-整理
4.HotSpot的算法實現
4.1枚舉根節點
4.2安全點
4.3 安全區域
5. 垃圾收集器
https://blog.csdn.net/tjiyu/article/details/53983650
6. 內存的分配和回收策略
名詞解釋:
VM區域總體分兩類,heap區和非heap區。
heap區又分爲:
Eden Space(伊甸園)、
Survivor Space(倖存者區)、有兩個,其中一個一定爲空
Old Gen(老年代)。
Minor GC :新生代垃圾收集動作,出現頻繁,回收速度快
Major GC /Full GC:發生在老年代GC,至少會包括一次Minor GC,速度比Minor GC慢十倍左右
非heap區又分:
Code Cache(代碼緩存區);
Perm Gen(永久代);
Jvm Stack(java虛擬機棧);
Local Method Statck(本地方法棧);
內存分配規則:
- Eden:Survivor From : Survivor To = 8:1:1
- Eden + Survivor = 新生代
- java堆 = 新生代內存 + 老年代內存
內存分配過程:
- 大多數情況下,對象在新生代Eden區分配,大對象(需要大量連續內存空間的java對象如數組,字符串)直接進入老年代
- 當Eden區沒有足夠的空間分配,虛擬機發起一次Minor GC(採用複製算法)
- Eden區域不能被回收的對象被放入到空的survivor(也就是To Survivor,同時Eden區域的內存會在垃圾回收的過程中全部釋放),另一個survivor(即From Survivor)裏不能被回收的對象也會被放入這個survivor(即To Survivor),然後To Survivor 和 From Survivor的標記會互換,始終保證一個survivor是空的。
- Survivor區中每“熬過”一次Minor GC,年齡就+1,當年齡到達一定的程度(默認15歲),就會被晉升到老年代Old Gen 中。
- 當老年代被放滿的之後,虛擬機會進行垃圾回收,稱之爲Major GC。由於Major GC除併發GC外均需對整個堆進行掃描和回收,因此又稱爲Full GC。
動態對象年齡判斷:
如果在Survivor空間中相同年齡所有對象大小的總和>Survivor空間的一半,年齡>=該年齡的對象就可3e入老年代
空間分配擔保: