浅谈Java虚拟机JVM的垃圾回收机制
1. 什么是垃圾
要回收垃圾,那么垃圾是什么?簡單的邏輯就是不會再被使用的內存對象唄。
?
2. 怎么判斷不再被使用
2.1 引用計數法。統計有多少個引用指向內存對象,如果沒有引用指向內存對象,那么該內存對象可以被當做垃圾。但是這邊有一個循環引用的問題,如一個方法內,創建了兩個新節點,它們之間互相引用,最終方法執行結束,方法內引用的對象應該被回收,但如果使用引用計數方案來處理,由于節點有被引用,會造成無法回收。
2.2 可達性分析。如果一個對象和GC Roots之間沒有鏈路連接,那么該對象可回收。但為了避免可達性分析過程中,其它用戶線程更改對象引用關系,會有GC停頓操作,也就是暫停Java所有工作線程。各個線程通過主動式查詢中斷標志位,然后決定是否中斷停在附近的安全點(方法調用、循環跳轉這些具有讓程序長時間執行的指令會產生安全點)。因為需要線程主動查詢中斷標志位,如果是那些睡眠或阻塞的線程,它們無法主動去查詢中斷標志位,因此它們會在進入睡眠或阻塞這些安全區域代碼時,標識自己進入了安全區域。當虛擬機發起垃圾回收時不需要管進入安全區域的線程,如果這些線程在垃圾回收時結束了安全區域代碼,那么會等待,直到JVM完成GC Roots枚舉。
2.3 GC Roots對象。可作為GC Roots對象的有四類:①虛擬機棧中局部變量表引用的對象;②類靜態屬性引用的對象;③方法區中常量引用的對象;④本地方法棧(帶有native修飾符的方法)中引用的對象。
?
3. 回收機制
確定了垃圾后,回收的機制:①如果“垃圾”對象沒有重寫finalize方法或者已經調用過finalize方法,那么該“垃圾”對象直接被回收;②如果“垃圾”對象重寫了finalize方法并且還沒有調用過finalize方法,那么會被放入F-Queue隊列中;稍后虛擬機會創建Finalize線程并執行finalize方法,如果對象要“拯救”自己,那么只要在finalize方法中再和GC Roots引用鏈上任何一個對象連接上即可。如果對象這時候還沒有逃脫,那么它就真的被回收了。
?
4. 回收方法區(也叫永久代)的廢棄常量和無用的類
雖然虛擬機規范不要求對方法區進行垃圾回收,但還是可以對廢棄常量和無用類進行回收。無用類的判斷條件:①任何實例都被回收;②加載該類的ClassLoad也被回收;③該類對應的java.lang.Class對象沒有在任何地方被引用。
?
?
總結
以上是生活随笔為你收集整理的浅谈Java虚拟机JVM的垃圾回收机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Concurrent包下的常用并发类和普
- 下一篇: java美元兑换,(Java实现) 美元