面試官:小夥子,你給我簡單講一下垃圾回收機制如何工做的吧?

垃圾回收機制是什麼?

垃圾回收是一種自動的存儲管理機制。 當一些被佔用的內存再也不須要時,就應該予以釋放,以讓出空間,這種存儲資源管理,稱爲垃圾回收。java

也就是說垃圾回收跟內存有關,那麼都有哪些內存呢算法

JVM內存

JVM將內存劃分爲五個區間.線程

JVM分爲五大內存空間,其中程序計數器、虛擬機棧、本地方法棧3個區域隨線程而生、隨線程而滅,所以這幾個區域的內存分配和回收都具有肯定性,就不須要過多考慮回收的問題,由於方法結束或者線程結束時,內存天然就跟隨着回收了。而Java堆區和方法區則不同,這部份內存的分配和回收是動態的,正是垃圾收集器所需關注的部分。對象

堆區的垃圾回收

什麼是垃圾

若是一個對象已經沒有任何一個地方引用它,它就是垃圾.生命週期

怎麼肯定是垃圾

引用計數法內存

給對象添加一個引用計數器,每當有一個地方引用它時,計數器加一。反之每當一個引用失效時,計數器減一。當計數器爲0時,則表示對象不被引用。資源

可達性分析虛擬機

設立若干根對象(GC Root),每一個對象都是一個子節點,當一個對象找不到根時,就認爲該對象不可達。class

觸發條件

Minor GC觸發機制效率

當年輕代滿時就會觸發Minor GC,這裏的年輕代滿指的是Eden代滿,Survivor滿不會引起GC。

FULL GC觸發機制

  1. 老年代空間不足
  2. 方法區空間不足
  3. 經過Minor GC後進入老年代的平均大小大於老年代的可用內存。
  4. 由Eden區、From Survivor區向To Survivor區複製時,對象大小大於To Space可用內存,則把該對象轉存到老年代,且老年代的可用內存小於該對象大小.
  5. System.gc()方法的調用,系統建議執行Full GC,可是沒必要然執行.

回收算法

標記-清除算法

該算法先標記,後清除,遍歷全部的GC Root,分別標記處可達的對象和不可達的對象,而後將不可達的對象回收。

這種算法的不足主要體如今效率和空間

從效率的角度講,標記和清除兩個過程的效率都不高,由於須要遍歷全部GC ROOT.

從空間的角度講,標記清除後會產生大量不連續的內存碎片, 內存碎片太多可能會致使之後程序運行過程當中在須要分配較大對象時,沒法找到足夠的連續內存而不得不提早觸發一次垃圾收集動做。

複製算法

將內存分爲兩塊,每次只使用一塊。當這一塊內存滿了,就將還存活的對象複製到另外一塊上,而且嚴格按照內存地址排列,而後把已使用的那塊內存統一回收。

優勢是:解決了標記-清除算法的碎片問題,可以獲得連續的內存空間
缺點是:浪費了一半內存

標記整理算法

複製算法在對象存活率較高時,持續複製效率很是低,老年代都是不易被回收的對象,針對老年代的特色,能夠採用標記整理算法,標記整理算法在標記-清除算法基礎上,它標記以後,不直接清理,是讓全部存活對象都向一端移動,而後直接清理掉邊界之外的內存.這樣既避免了對象存活率較高時的持續複製,也避免了內存碎片的出現.適用於老年代.

分代收集算法

現代商用虛擬機基本都採用分代收集算法來進行垃圾回收。這種算法沒什麼特別之處,就是上面內容的結合.

它是對內存中的對象按照生命週期的長短,以及所在區域的不一樣進行劃分.

堆區分爲新生代,老年代.

方法區爲持久代.

新生代就是活不了多久就死亡的對象,通常在堆內存.好比局部變量.

老年代是活的久但也會死亡的對象,通常在堆內存.好比一些生命週期長的對象.

持久代是不死的對象,通常在方法區.好比加載的class信息.

不一樣的年代使用不一樣的垃圾回收算法.

新生代使用複製算法.

老年代使用標記整理算法.

方法區的垃圾回收

持久代也就是方法區,Java虛擬機規範中說過能夠不要求虛擬機在方法區實現垃圾收集,由於和堆區的垃圾回收效率相比,它的回收效率實在過低,可是此部份內存區域也是能夠被回收的。

持久代和堆區的新生代和老年代不同.方法區主要回收的內容是廢棄常量和無用的類。

對於廢棄常量也可經過引用的可達性來判斷,可是對於無用的類則須要同時知足下面3個條件:

  • 該類全部的實例都已經被回收,也就是Java堆中不存在該類的任何實例;
  • 加載該類的ClassLoader已經被回收;
  • 該類對應的java.lang.Class對象沒有在任何地方被引用,沒法在任何地方經過反射訪問該類的方法。.

最後

你們看完有什麼不懂的能夠在評論區問我,感受對你有幫助的話記得給我點個贊謝謝!

相關文章
相關標籤/搜索