在Java中,對象的生命週期包含下面幾個階段:
1. 創建階段(Created)
2. 應用階段(In Use)
3. 不可見階段(Invisible)
4. 不可達階段(Unreachable)
5. 收集階段(Collected)
6. 終結階段(Finalized)
7. 對象空間重分配階段(De-allocated)
圖1. JavaObject Life Cycle
在創建階段系統通過以下的幾個步驟來完畢對象的創建過程
一旦對象被創建,並被分派給某些變量賦值,這個對象的狀態就切換到了應用階段
對象至少被一個強引用持有着。
當一個對象處於不可見階段時,說明程序本身不再持有該對象的任何強引用(例如:局部變量剛超出作用域,局部變量表中slot還沒有被回收,即還沒來得及修改slot,導致slot中依然存儲的對象引用,依然還是可達GCroot狀態)
簡單說就是程序的運行已經超出了該對象的作用域了。
舉比例如以下圖:本地變量count在25行時已經超出了其作用域,則在此時稱之爲count處於不可視階段。當然這樣的情況編譯器在編譯的過程中會直接報錯了。
圖2. 不可見階段演示樣例
對象處於不可達階段是指該對象不再被任何強引用所持有。
**不可到達GCroot**
當垃圾回收器發現該對象已經處於「不可達階段」而且垃圾回收器已經對該對象的內存空間又一次分配做好準備時,則對象進入了「收集階段」。假設該對象已經重寫了finalize()方法,則會去運行該方法的終端操作。
這裏要特別說明一下:不要重載finazlie()方法!原因有兩點:
在分配該對象時,JVM須要在垃圾回收器上註冊該對象,以便在回收時可以運行該重載方法;在該方法的運行時須要消耗CPU時間且在運行完該方法後纔會又一次運行回收操作,即至少須要垃圾回收器對該對象運行兩次GC。
在finalize()方法中,假設有其他的強引用再次持有該對象,則會導致對象的狀態由「收集階段」又又一次變爲「應用階段」。這個已經破壞了Java對象的生命週期進程,且「復活」的對象不利用興許的代碼管理。
當對象運行完finalize()方法後仍然處於不可達狀態時,則該對象進入終結階段。在該階段是等待垃圾回收器對該對象空間進行回收。
垃圾回收器對該對象的所佔用的內存空間進行回收或者再分配了,則該對象徹底消失了,稱之爲「對象空間又一次分配階段」。