每日三道面試題,通往自由的道路6——JVM

太子爺哪吒發表於2021-06-28

茫茫人海千千萬萬,感謝這一秒你看到這裡。希望我的面試題系列能對你的有所幫助!共勉!

願你在未來的日子,保持熱愛,奔赴山海!

每日三道面試題,成就更好自我

今天我們繼續聊聊JVM的話題吧!

1. 那你知道什麼時候才會觸發Full GC

  1. 在老年代空間不足的時候:
    老年代空間只有在新生代物件發生minor Gc轉入或者是直接建立為大物件、大陣列時出現空間不足的現象,當JVM執行Full GC後空間仍然不足,則丟擲如下錯誤:java.lang.OutOfMemoryError: Java heap space

    解決措施:儘量做到讓物件在Minor GC階段被回收、讓物件在新生代多存活一段時間及不要建立過大的物件及陣列。

  2. 在我們程式中直接呼叫了System.gc, 也會直接出發Full GC。

  3. 在永久代空間滿
    永久代中存放的為一些class的資訊等,當系統中要載入的類、反射的類和呼叫的方法較多時,永久代空間可能會被佔滿,在未配置的時候採用這CMS垃圾收集器的情況下會執行Full GC。如果經過Full GC仍然回收不了,那麼JVM會丟擲如下錯誤資訊:java.lang.OutOfMemoryError: PermGen space

    解決措施:可採用的方法為增大永久代空間或轉為使用CMS GC。

  4. 在CMS垃圾收集器出現promotion failed(晉升失敗)和concurrent mode failure(併發模式故障)

    對於如果我們採用CMS垃圾收集器進行老年代GC的程式而言,我們就需要主要在GC日誌中是否有晉升失敗和併發模式故障兩種狀況,當這兩種狀況出現時可能會觸發Full GC:

    晉升失敗(promotion failed) 是在新生代進行Minor GC時,倖存區中放不下、而物件只能放入老年代,而此時老年代也放不下造成的。

    concurrent mode failure是CMS轉悠的錯誤,即併發清楚執行緒和工作執行緒同時工作,清理出來老年代的空間不足以存放由新生代晉升到老年代的物件。

    解決措施:減少年輕代大小,避免放入老年代時需要分配大的空間,同時調整觸發Full GC時的比率以及將觸發CMS GC的閥值適當增大

不錯不錯,這都難不倒你!

2. JVM中四種引用你有了解過嗎?

  • 強引用:垃圾收集器不會回收被強引用的物件。

    在 Java 中最常見的就是強引用, 把一個物件賦給一個引用變數,這個引用變數就是一個強引用。即在我們寫類似這樣User user = new User(),我們new出來的user物件就是一個強引用了!

    當一個物件被強引用變數引用時,它處於可達狀態,它是不可能被垃圾回收機制回收的即使在記憶體不足的情況下,JVM寧願丟擲OutOfMemory錯誤也不會回收這種物件。

  • 軟引用:在沒有被強引用物件,當系統要發生記憶體溢位的異常之前,會將其列為回收範圍,進行第二次回收。

    軟引用需要用 SoftReference 類來實現,對於只有軟引用的物件來說,當系統記憶體足夠時它不會被回收,當系統記憶體空間不足時它會被回收。軟引用通常用在對記憶體敏感的程式中。

  • 弱引用:具有弱引用的物件擁有更短暫的生命週期。在沒有被強引用物件,只能存活在下一次垃圾收集器前。無論記憶體夠不夠。

    弱引用需要用 WeakReference 類來實現,它比軟引用的生存期更短,對於只有弱引用的物件來說,只要垃圾回收機制一執行,不管 JVM 的記憶體空間是否足夠,總會回收該物件佔用的記憶體。

  • 虛引用:無法通過虛引用取得一個物件例項,設定虛引用的目的是為了能在這個物件被垃圾收集器回收時收到一個通知。 虛引用的主要作用是跟蹤物件被垃圾回收的狀態。

可以,那問你最後一道:

3. 說說你知道的幾種主要的JVM引數

  1. 堆設定

    • -Xms:初始堆大小
    • -Xmx:最大堆大小
    • -XX:NewSize=n:設定新生代大小
    • -XX:NewRatio=n:設定年輕代和年老代的比值。如:為3,表示新生代與老年代比值為1:3,新生代佔整個新生代老年代和的1/4
    • -XX:SurvivorRatio=n:新生代中Eden區與兩個Survivor區的比值。注意Survivor區有兩個。如:3,表示Eden:Survivor=3:2,一個Survivor區佔整個新生代的1/5
    • -XX:MaxPermSize=n:設定持久代大小
  2. 收集器設定

    • -XX:+UseSerialGC:設定序列收集器
    • -XX:+UseParallelGC:設定並行收集器
    • -XX:+UseParalledlOldGC:設定並行老年代收集器
    • -XX:+UseConcMarkSweepGC:設定併發收集器
  3. 並行收集器設定

    • -XX:ParallelGCThreads=n:設定並行收集器收集時使用的CPU數。並行收集執行緒數。

    • -XX:MaxGCPauseMillis=n:設定並行收集最大暫停時間

    • -XX:GCTimeRatio=n:設定垃圾回收時間佔程式執行時間的百分比。公式為1/(1+n)

  4. 併發收集器設定

    • -XX:+CMSIncrementalMode:設定為增量模式。適用於單CPU情況。

    • -XX:ParallelGCThreads=n:設定併發收集器新生代收集方式為並行收集時,使用的CPU數。並行收集執行緒數。

  5. JVM 調優的引數

    • -Xms2g:初始化推大小為 2g;
    • -Xmx2g:堆最大記憶體為 2g;
    • -XX:NewRatio=4:設定年輕的和老年代的記憶體比例為 1:4;
    • -XX:SurvivorRatio=8:設定新生代 Eden 和 Survivor 比例為 8:2;
    • –XX:+UseParNewGC:指定使用 ParNew + Serial Old 垃圾回收器組合;
    • -XX:+UseParallelOldGC:指定使用 ParNew + ParNew Old 垃圾回收器組合;
    • -XX:+UseConcMarkSweepGC:指定使用 CMS + Serial Old 垃圾回收器組合;
    • -XX:+PrintGC:開啟列印 gc 資訊;
    • -XX:+PrintGCDetails:列印 gc 詳細資訊。

小夥子不錯嘛!今天就到這裡,期待你明天的到來,希望能讓我繼續保持驚喜!

注: 如果文章有任何錯誤和建議,請各位大佬盡情留言!如果這篇文章對你也有所幫助,希望可愛親切的您給個三連關注下,非常感謝啦!也可以微信搜尋太子爺哪吒公眾號私聊我,感謝各位大佬!

相關文章