面試題之GC是什麼?爲什麼要有GC?

一、GC是什麼?爲什麼要有GC?

參考回答:GC是垃圾收集的意思,內存處理是開發人員容易出現問題的地方,忘記或者錯誤地內存回收會導致程序或者系統的不穩定甚至崩潰,Java提供的垃圾回收機制可以自動檢測對象是否超過作用域從而達到自動回收的目的。

二、簡述Java垃圾回收機制

參考回答:在Java開發中,程序員並不需要顯式去釋放一個對象的內存的,而是由虛擬機自動進行管理。在JVM中,有一個低優先級的垃圾回收線程,在正常情況下這個線程是不會執行的,只有在虛擬機空閒或者當前堆內存不足時,纔會觸發執行,掃描那些沒有被任何引用的對象,並將它們添加到要回收的對象集合中,然後進行回收操作。

三、如何判斷一個對象是否存活?GC對象的判斷方法?

判斷一個對象是否存活有兩種方法:引用計數法和可達性分析法

  • 引用計數法

    所謂引用計數法就是給每一個對象設置一個引用計數器,每當有一個地方引用這個對象時,就將計數器加1,引用失效時,計數器就減1。當一個對象的引用計數器爲0時,說明此對象沒有被其他對象引用,也就是死對象,將會被GC回收。
    缺陷:無法解決循環引用問題,也就是說對象A引用對象B,對象B反過來引用對象A,那麼此時A、B對象的引用計數器都不爲0,也就造成無法完成垃圾回收,所以主流的虛擬機都沒有采用這種算法。

  • 可達性分析法

    從一個被稱爲GC Roots的對象開始往下搜索,如果一個對象到GC Roots沒有任何引用鏈相連時,則說明此對象不可用。
    可以作爲GC Roots的對象有以下幾種:

  1. 虛擬機棧中引用的對象
  2. 方法區類靜態屬性引用的對象
  3.  方法區常量池引用的對象
  4.  方法棧JNI引用的對象

    當一個對象不可達GC Roots時,這個對象並不會立馬被回收,而是處於一個死緩的階段,如果要真正的回收需要經歷兩次標記。如果對象在可達性分析中沒有與GC Roots的引用鏈,那麼此時就會被第一次標記並且進行一次篩選,篩選的條件是是否有必要執行finalize()方法。當對象沒有覆蓋finalize()方法或者已被虛擬機調用過,那麼就認爲是沒有必要的。如果該對象有必要執行finalize()方法,那麼這個對象就會放在一個稱爲F-Queue的隊列中,虛擬機會觸發一個Finalize()線程去執行,此線程是低優先級的,並且虛擬機不會承諾一直等待它運行完,這是因爲如果finalize()方法執行緩慢或者發生了死鎖,那麼就是造成F-Queue隊列一直等待,造成了內存回收系統的崩潰。GC對處於 F-Queue隊列中的對象進行第二次標記,這時,該對象將會被移出“即將回收”集合,等待回收。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章