gc是JAVA語言魅力之所在,也是面試過程中常常提及的點,下面分析下jvm怎麼回收垃圾!
1,被動回收:首先需要明確的是,jvm有一套自動回收垃圾的機制,jvm中的執行緒在掃描的時候如果發現有不可達物件,就進行標記,表示這個物件佔用的記憶體可以回收(這個時候還沒回收)。
這裡的重點是什麼是不可達物件?jvm會選擇一個不會被回收的變數(static final),或者本地方法棧中的物件,或者靜態(static)的物件作為GC ROOTS(根節點),其他所有建立的物件引用都會掛在這個根節點上,變成一顆類似樹的結構。
在回收垃圾的時候,從根節點開始遍歷,如果發現有物件引用遍歷不到,也就是沒掛在根節點上,比如A引用B,B引用C,但是A掛在樹上的引用被剪斷,那麼ABC物件就屬於不可達物件,也就是需要回收的物件!
回收執行緒再次掃描的時候發現之前被搭上標記的物件,並呼叫類中預設繼承的finalize方法,該方法會檢測是否有引用繼續指向待回收物件,如有引用,則這些物件重新使用不在回收,如果確定回收的物件,會放入一個專門回收的佇列中,由專門的執行緒進行清空記憶體!
2,主動回收:呼叫system.gc方法進行物件回收,但是正如上面所說,呼叫了之後,只是打上可回收標記,真正的釋放記憶體還需要jvm自己來進行!
gc是JAVA語言魅力之所在,也是面試過程中常常提及的點,下面分析下jvm怎麼回收垃圾!
1,被動回收:首先需要明確的是,jvm有一套自動回收垃圾的機制,jvm中的執行緒在掃描的時候如果發現有不可達物件,就進行標記,表示這個物件佔用的記憶體可以回收(這個時候還沒回收)。
這裡的重點是什麼是不可達物件?jvm會選擇一個不會被回收的變數(static final),或者本地方法棧中的物件,或者靜態(static)的物件作為GC ROOTS(根節點),其他所有建立的物件引用都會掛在這個根節點上,變成一顆類似樹的結構。
在回收垃圾的時候,從根節點開始遍歷,如果發現有物件引用遍歷不到,也就是沒掛在根節點上,比如A引用B,B引用C,但是A掛在樹上的引用被剪斷,那麼ABC物件就屬於不可達物件,也就是需要回收的物件!
回收執行緒再次掃描的時候發現之前被搭上標記的物件,並呼叫類中預設繼承的finalize方法,該方法會檢測是否有引用繼續指向待回收物件,如有引用,則這些物件重新使用不在回收,如果確定回收的物件,會放入一個專門回收的佇列中,由專門的執行緒進行清空記憶體!
2,主動回收:呼叫system.gc方法進行物件回收,但是正如上面所說,呼叫了之後,只是打上可回收標記,真正的釋放記憶體還需要jvm自己來進行!