Java垃圾回收機制
自動垃圾回收是一種在堆內存中找出哪些對象在被使用,還有哪些對象沒被使用,並且將后者刪掉的機制。
所謂使用中的對象(已引用對象),指的是程序中有指針指向的對象;而未使用中的對象(未引用對象),則沒有被任何指針給指向,因此占用的內存也可以被回收掉。
在用 C 之類的編程語言時,程序員需要自己手動分配和釋放內存。而 Java 不一樣,它有垃圾回收器,釋放內存由回收器負責。本文接下來將介紹垃圾回收機制的基本過程。
總體GC經過三個過程:標記 --> 清除 -->壓縮
1. 標記:首先第一次GC時,回收器會把對象標記使用與未使用
上圖中,藍色部分表示已引用對象,橙色表示未引用對象。
2. 清除:這一步刪除所有未引用的對象
3. 壓縮:為了提升性能,刪除了未引用對象后,還可以將剩下的已引用對象放在一起(壓縮),這樣就能更簡單快捷地分配新對象了。
GC新生代對象移動到老年代的情況
上圖為JVM模擬圖
對象首先在Eden區分配空間,一旦eden區滿了,就會觸發第一次GC,進行小型垃圾回收機制,把存活的對象放在第一個S區,並清除Eden空間,
在下一次GC時,重復之前的操作,不過特別的時會把第一個S區的對象移動到第二個S區,並清除Eden和第一個S區,這時,S區已經有了不同年齡的對象。
在下一次Minor GC中,會重復同樣的操作。不過,這一次Survivor區會交換。被引用的對象移動到S,。幸存的對象增加年齡。Eden區和S被清空。
新生代到老年代
1. 當Eden和一個Survivor區中依然存活的對象無法放入到Survivor中,則通過分配擔保機制提前轉移到老年代中。
2. 如果對象的體積太大,新生代無法容納的話也會繞過新生代,直接在老年代分配空間。
虛擬機對每個對象定義了一個對象年齡(Age)計數器。當年齡增加到一定的臨界值時,就會晉升到老年代中,該臨界值由參數:-XX:MaxTenuringThreshold來設置。
如果對象在Eden出生並在第一次發生MinorGC時仍然存活,並且能夠被Survivor中所容納的話,則該對象會被移動到Survivor中,並且設Age=1;
4.動態對象年齡判斷
虛擬機並不總是要求對象的年齡必須達到MaxTenuringThreshold才能晉升到老年代,如果在Survivor區中相同年齡(設年齡為age)的對象的所有大小之和超過Survivor空間的一半,
年齡大於或等於該年齡(age)的對象就可以直接進入老年代,無需等到MaxTenuringThreshold中要求的年齡。
參考鏈接:https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html#
https://www.cnblogs.com/yuandluck/p/9484495.html