四種GC算法
GC垃圾回收,首先需要判斷哪些對象需要回收
判斷對象存活
可達性分析:
從GC Roots開始向下查詢,如果一個對象到任何一個GC Root對象都沒有一個引用鏈相連的話,說明此對象不可用。
四個GC Root對象
- JVM棧中引用的對象
- 方法區靜態屬性引用的對象
- 方法區中常量引用的對象
- 本地棧中JNI中引用的對象
四種GC算法
引用計數:
每個對象都有一個引用計數屬性,多一個引用+1,少一個引用-1,為0的時候代表可以回收。
致命缺點:無法解決循環引用
復制算法:
將內存分為兩塊,當一塊內存用完了,就將存活的對象復制到另一塊內存中。
優點:空間連續,沒有內存碎片,運行效率高。
缺點:占用內存,如果復制長期生存的對象,會導致效率低。
主要用在新生代,因為新生代對象存活率低。
標記-清除:
先標記出需要清除的對象,再將標記的對象回收。
優點:占用內存小
缺點:
(1)需要進行兩次動作,標記和清除,所以效率低。
(2)回收完之后,內存不連續,會有內存碎片
標記-壓縮:
先標記出需要清除的對象,但是不進行回收,而是讓所有存活對象都向一段移動,然后清除邊界之外的內存空間。
優點:占用內存小,沒有內存碎片
缺點:效率低
分代收集:
根據Java堆的新生代和老年代的特點,選用不同的回收算法。新生代內存空間大,對象會大量死去,回收頻繁,使用效率高的復制算法,只需要每次復制少量存活下來的對象即可。老年代內存空間小,對象存活率高,使用標記-清除/標記-壓縮算法。