??大家好,我是陳哈哈,北漂五年,相信大家和我一樣,
都有一個大廠夢,作為一名資深Java選手,深知面試重要性,接下來我準備用100天時間,基于Java崗面試中的高頻面試題,以每日3題的形式,帶你過一遍熱門面試題及恰如其分的解答,
??一路走來,隨著問題加深,發現不會的也愈來愈多,但底氣著實足了不少,相信不少朋友和我一樣,榷訓月累才是最有效的學習方式!想起高三時一個同學的座右銘:只有沉下去,才能浮上來,共勉(juan),

坐標:北京大興國際機場
車票
- 面試題1:簡單說一下java的垃圾回識訓制,
- 面試題2:JVM會在什么時候進行GC呢?
- 追問1:介紹一下不同代空間的垃圾回識訓制
- 追問2:能說一下新生代空間的構成與執行邏輯么?
- 追問3:說一下發生OOM時,垃圾回識訓制的執行流程,
- 面試題3:Full GC 、Major GC和 Minor GC有什么不同
- 每日小結
??本欄目Java開發崗高頻面試題主要出自以下各技術堆疊:Java基礎知識、集合容器、并發編程、JVM、Spring全家桶、MyBatis等ORMapping框架、MySQL資料庫、Redis快取、RabbitMQ訊息佇列、Linux操作技巧等,
??地球人都知道,Java有個東西叫垃圾收集器(GC),它讓創建的物件不需要像c/c++那樣delete、free掉,你能不能談談,GC是在什么時候,對什么東西,做了什么事情?
??這個是經典拋磚引玉的問法,既能看出我們對GC掌握的情況,也能從多點切入深問,看著三句話,其實每句話的知識點都夠我們喝一壺的,JVM接下來三篇會以:什么時候進行GC、對哪些物件、做哪些處理三個角度的面試問題進行整理,來吧,卷,
??本篇的內容主要基于在什么時候進行GC這個方向來學習,大家有問題請在評論區噴我或互噴,噴出來的問題才會印象深刻,
面試題1:簡單說一下java的垃圾回識訓制,
??任何語言在運行程序中都會創建物件,也就意味著需要在記憶體中為這些物件在記憶體中分配空間,如果這些物件只增加不減少,那么堆空間很快就會被耗盡,因此在這些物件失去使用的意義的時候,需要釋放掉這些內容,保證記憶體能夠提供給新的物件使用,對于物件記憶體的釋放就是垃圾回識訓制,也叫做gc(Garbage Collection,GC),

??對于java開發者來說gc是一個雙刃劍,像C語言的垃圾回收是人工的,作業量大,但是可控性高,而java是自動化的,但是可控性很差,甚至有時會出現記憶體溢位的情況,記憶體溢位也就是jvm分配的記憶體中物件過多,超出配置的JDK最大可分配記憶體的大小,

課間休息,又來秀一下來自咱們群里同學的搬磚工地,坐標:武漢,
作者:相識何必再相逢
面試題2:JVM會在什么時候進行GC呢?
JVM常在以下幾種場景時進行GC操作:
- 在cpu空閑的時候自動進行回收
- 主動呼叫System.gc()后嘗試進行回收,是否回收由JVM決定,
Eden區域滿了,或者新創建的物件大小 > Eden所剩空間,執行Minor GC,升到老年代的物件大于老年代剩余空間的時候執行Full GC,或者Young GC中發生promotion failure`強制Full GC ,- 在堆記憶體存盤滿了之后進行GC,如gc與非gc時間耗時超過了GCTimeRatio的限制引發OOM
??
YGC出現promotion failure的場景: promotion failure發生在Young GC, 如果Survivor區當中存活物件的年齡達到了設定值,會就將Survivor區當中的物件拷貝到老年代,如果老年代的空間不足,就會發生promotion failure, 強制進行Full GC ,
追問1:介紹一下不同代空間的垃圾回識訓制
新生代(Young generation):
??從年輕代空間(包括 Eden 和 Survivor 區域)回收記憶體被稱為 Minor GC,因為 Java 物件大多都具備朝生夕滅(很快不再使用)的特性,所以 Minor GC 非常頻繁,一般回收速度也比較快,這一定義既清晰又易于理解,,
老年代(Old generation):
??物件沒有變得不可達,并且從新生代周期中存活了下來,會被拷貝到這里,其區域分配的空間要比新生代多,也正由于其相對大的空間,發生在老年代的GC次數要比新生代少得多,清理老年代記憶體一般直接是 Full GC來清理,
默認的新生代(Young generation)、老年代(Old generation)所占空間比例為 1 : 2 ,
持久代(Permanent generation):
??也稱之為方法區(Method area):用于保存類常量以及字串常量,注意,這個區域不是用于存盤那些從老年代存活下來的物件,這個區域也可能發生GC,發生在這個區域的GC事件為 Major GC ,
??出現了 Major GC,經常會伴隨至少一次的 Minor GC(但非絕對的,ParallelScavenge 收集器的收集策略里就有直接進行 Major GC 的策略選擇程序) ,MajorGC 的速度一般會比 Minor GC 慢 10倍以上,只不過在這個區域發生GC的條件非常嚴苛,必須符合以下三種條件才會被回收:
- 所有實體被回收
- 加載該類的ClassLoader 被回收
- Class 物件無法通過任何途徑訪問(包括反射)
追問2:能說一下新生代空間的構成與執行邏輯么?
新生代(Young generation)用來保存那些第一次被創建的物件,它被分成三個空間:
- 一個伊甸園空間(Eden)
- 兩個幸存者空間(From Survivor、To Survivor)
默認新生代空間的分配:Eden : From : To =8 : 1 : 1

每個空間的執行說明如下:
-
絕大多數
剛剛被創建的物件會存放在伊甸園空間(Eden),當一個物件被判定為死亡的時候,GC 就有責任來回收掉這部分物件的記憶體空間, -
新生代是 GC 最頻繁區域,當物件在 Eden ( 包括一個 Survivor 區域,假設是 from 區域 ) 出生后,在經過一次 Minor GC后,如果物件還存活,并且能夠被另外一塊 Survivor 區域所容納(上面已經假設為 from 區域,這里應為 to 區域,即 to 區域有足夠的記憶體空間來存盤 Eden 和 from 區域中存活的物件 ),則使用復制演算法將這些仍然還存活的物件復制到另外一塊 Survivor 區域 ( 即 to 區域 )中,然后清理所使用過的 Eden以及 Survivor 區域( 即from 區域 ),并且將這些物件的年齡設定為1,可見,兩個幸存者空間,必須有一個是保持空的, -
此后,物件在 Survivor 區
每熬過一次 Minor GC,就將物件的年齡 + 1,當物件的年齡達到某個值時 ( 默認是 15 歲,可以通過引數 -XX:MaxTenuringThreshold 來設定),這些物件就會成為老年代, -
但也有例外的,對于一些較大的物件 (即需要分配一塊較大的連續記憶體空間 ) 則是直接進入到老年代,,
如何判定物件死亡:通過參考計數法、可達性分析演算法判斷是否還存在參考,以及結合根據物件參考強度判斷;
以下流程評論區朋友們有歧義,經查證確實是有問題的,保留下來引以為戒,
- 絕大多數
剛剛被創建的物件會存放在伊甸園空間(Eden), - 在伊甸園空間執行第一次GC(Minor GC)之后,存活的物件被移動到其中一個幸存者空間(Survivor),
- 此后,每次伊甸園空間執行GC后,存活的物件會被堆積在同一個幸存者空間,
- 當一個幸存者空間飽和,
還在存活的物件會被移動到另一個幸存者空間,然后會清空已經飽和的哪個幸存者空間,可見,兩個幸存者空間,必須有一個是保持空的, - 在以上步驟中重復N次(N = MaxTenuringThreshold(
年齡閥值設定,默認15))依然存活的物件,就會被移動到老年代,
??當然,也有例外出現,對于一些比較大的物件(需要分配一塊比較大的連續記憶體空間)則直接進入到老年代,一般在Survivor 空間不足的情況下發生,
追問3:說一下發生OOM時,垃圾回識訓制的執行流程,
- 對于一個很大的物件或陣列,我們會首先在Eden 嘗試創建,如果Eden區記憶體不夠,創建不了,則
觸發Minor GC; - Minor GC完成后繼續嘗試在Eden區存放,發現仍然放不下;
- 嘗試直接進入老年代,老年代也放不下
觸發 FULL GC清理老年代的空間- FULL GC完成后嘗試往老年代里放,還是放不下
- OOM

北漂鐵子們,快來猜猜這是哪里?
作者:淘氣的小蘋果
面試題3:Full GC 、Major GC和 Minor GC有什么不同
??我們見過很多 GC 名詞如:Minor GC、Young GC、Full GC、Old GC、Major GC、Mixed GC等,那么這么多GC如何進行大致區分?下面我們參考 R 大在知乎上的回答:
針對 HotSpot VM 的實作,它里面的 GC 其實準確分類有兩種:
- Partial GC(區域 GC): 并不收集整個 GC 堆的模式
- Young GC: 只收集 Young Gen 的 GC,
Young GC 還有種說法就叫做 Minor GC,兩者是一個意思; - Old GC: 只收集 old gen 的 GC,只有垃圾收集器 CMS 的 concurrent collection 是這個模式;
- Mixed GC: 收集整個 Young Gen 以及部分 old gen 的 GC,只有垃圾收集器 G1 有這個模式;
- Full GC(全域 GC):
收集整個堆,包括新生代,老年代,永久代(在 JDK 1.8 及以后,永久代被移除,換為 metaspace 元空間)等所有部分的模式;
接下來讓我們再來了解下各個 GC:
(1)Minor GC / Young GC
??首先我們先來看下 Minor GC / Young GC,大家都知道,新生代(Young Gen)也可以稱之為年輕代,這兩個名詞是等價的,那么在年輕代中的 Eden 記憶體區域被占滿之后,實際上就需要觸發年輕代的 GC,或者是新生代的 GC,
??其實就是所謂的 Minor GC,也可以稱之為 Young GC,
(2)Old GC
??所謂的老年代 GC,稱之為 Old GC 更加合適一些,因為從字面意義上就可以理解,這就是所謂的老年代 GC,
(3)Full GC
??對于 Full GC,可以說 Full GC 指的是針對新生代、老年代、永久代的全體記憶體空間的垃圾回收,所以稱之為 Full GC,
(4)Major GC
??上面我們提到,Major GC用于處理方法區的物件,這個區域不是用于存盤那些從老年代存活下來的物件,這個區域也可能發生GC,發生概率很低,
(5)Mixed GC
??Mixed GC 是 G1 中特有的概念,其實說白了,主要就是說在 G1 中,一旦老年代占據堆記憶體的 45%(-XX:InitiatingHeapOccupancyPercent:設定觸發標記周期的 Java 堆占用率閾值,默認值是 45%,這里的Java 堆占比指的是 non_young_capacity_bytes,包括 old + humongous),就要觸發 Mixed GC,此時對年輕代和老年代都會進行回收,Mixed GC 只有 G1 中才會出現,
每日小結
??今天我們復習了面試中常考的JVM相關的三個問題,你做到心中有數了么?對了,如果你的朋友也在準備面試,請將這個系列扔給他,如果他認真對待,肯定會感謝你的!!好了,今天就到這里,學廢了的同學,記得在評論區留言:打卡,,給同學們以激勵,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/294705.html
標籤:java
