天天看點

JVM的GC垃圾回收面試小結

1、JVM的元件有什麼?

答:jvm主要包含5個核心結構:虛拟機棧,本地方法棧,堆,方法區,程式計數器。

2、JVM中哪些結構是線程共享的,哪些是線程私有的?

答:線程共享的有堆(儲存建立的執行個體),方法區(主要儲存存一些靜态常量,基本類型變量)。

線程私有的是虛拟機棧,本地方法棧還有線程計數器。

3、JVM中的虛拟機棧幀中儲存了什麼?

答:虛拟機棧幀中儲存了局部變量表,動态連結,操作數棧,方法傳回位址

4、gvm做垃圾回收的時候什麼時候觸發full gc什麼時候觸發senior gc?

答:說觸發fullgc和senior gc前首先得明确兩個概念:(1)什麼是gc垃圾回收,gc垃圾回收主要發生在jvm的堆中,堆又被分為新生代,老年代,元空間(持久帶),新生代裡又被劃分為3個區域,eden區,from區和to區,(2)什麼被對象被gc認為是垃圾,有兩種方法确認可達性分析法和引用計數器,當通過可達性分析法找到的對象不認為是垃圾,找不到引用的被認為是垃圾,引用計數器是當引用次數為0時被認為是垃圾。

明确以上兩個概念後再談談什麼時候觸發full gc 什麼時候觸發senior gc。建立的執行個體首先出現在edan區當無法在eden區建立新的執行個體時,eden區和form區會經過可達性算法分析後将不活躍的執行個體對象回收,釋放空間,這就是觸發了一次senior gc(值得一提的是在此處采用的是複制回收的垃圾回收算法,統一将eden區和from區的活躍對象複制到to區,然後回收不活躍對象)。那麼什麼時候觸發full gc呢?這個分為比較多的情況

  1. 當調用System.gc()時,系統會要求觸發full gc,但是不一定執行
  2. 當老年代沒有空間了,則會觸發一次full gc。
  3. 當從新生代經過8次(預設)senior gc存活下來的對象向老年代移動時,老年代空間不足以接收新生代對象時,觸發full gc。
  4. 方法區空間不足
  5. 當新生代想老年代轉移空間大小平均大于老年代剩餘空間時觸發full gc。

5、當記憶體中變量A引用了變量B,JVM是如何釋放記憶體呢?

答:這裡涉及兩個記憶體回收的算法,一個是引用計數法,另一個是可達分析法。引用計數法對于這種情況是處理不了的,得用可達性分析法:通過一系列稱為“GC Roots”的對象作為起始點,從這些節點開始向下搜尋,搜尋走過的路徑稱為“引用鍊”,當一個對象到 GC Roots 沒有任何的引用鍊相連時(從 GC Roots 到這個對象不可達)時,證明此對象不可用。這裡可達性分析法可以解決這種循環引用的情況。

6、記憶體溢出與記憶體洩漏的差別是什麼?

答:1、記憶體溢出是指你要求配置設定的記憶體嗎,系統給不了你了。空間不足。

2、記憶體洩漏是指程式在申請記憶體後,無法釋放已申請的記憶體空間,一次記憶體洩露危害可以忽略,但記憶體洩露堆積後果很嚴重,無論多少記憶體,遲早會被占光。