1. 程式人生 > >面試官,不要再問我“Java 垃圾收集器”了

面試官,不要再問我“Java 垃圾收集器”了

如果Java虛擬機器中標記清除演算法、標記整理演算法、複製演算法、分代演算法這些屬於GC收集演算法中的方法論,那麼“GC收集器”則是這些方法論的具體實現。

在面試過程中這個深度的問題涉及的比較少,但對於理解上面的這些演算法有很好的幫助。如果能夠如數家珍,也是面試中的加分項,還是那句話,畢竟面試官的時間也不多了。

概念準備

在學習Java GC收集器之前,需要先了解一些內容和概念,首先如果沒有學習《面試官,不要再問我“Java GC垃圾回收機制”了》的可先學習該篇文章,瞭解基本演算法方法論。

下面瞭解幾個概念以幫助後面的學習:執行緒暫停(Stop The World)、安全點(Safepoint)、安全區(Safe region)。

在執行可達性分析的時候會出現在分析的過程中物件關係引用等發生了變化,為了保證分析的準確性,就必須在分析的過程中暫停所有Java執行緒,Sun將這一事件稱作“Stop The World”。

那麼,什麼時候暫停合適呢?並不是所有的時刻都可以暫停所有執行緒進行GC的,只有到達某些點才可以進行GC操作,這些點就稱作安全點(Safepoint)。

安全點的設定不能太少,那樣GC等待的時間就會太長,但也不能太多否則會增加執行時的負擔。

所以,安全點的選定基本上是以程式“是否具有讓程式長時間執行的特徵”為標準進行選定的。比如,迴圈的末尾、方法臨返回前/呼叫方法的call指令後、可能拋異常的位置等。

HotSpot採用主動中斷的方式,讓執行執行緒在執行期輪詢是否需要暫停的(GC設定的)標誌,若需要則中斷掛起。

對於正在執行的執行緒,可以主動執行到安全點並暫停執行,但是對於那些正在Sleep或阻塞的執行緒,當它們重新執行時可能已經過了安全點,但此時GC可能還沒完成垃圾回收,這種情況該怎麼辦呢?

於是就有了安全區(Safe region)的概念,安全區是一塊區域,在該區域中引用都不會被修改。比如,執行緒進入到安全區的時候先標識自己進入了安全區,等它被喚醒準備離開時,先檢查GC是否完成,如果完成則可以離開,否則就在安全區等待。

瞭解了上面的基本概念之後,下面正式進入垃圾收集器的講解。

垃圾收集器分類

先通過下圖瞭解一下Hotspot的8種垃圾收集器及其應用。

兩個收集器之間的連線,表示它們可以搭配使用。收集器所處的區域表示它是屬於新生代收集器還是老年代收集器。其中ZGC為Java11引入的新的垃圾收集器。

預設垃圾收集器

不同Java版本採用的預設收集器如下。

Serial收集器

Serial收集器是最基本、發展歷史最悠久的收集器,是一個單執行緒的收集器。在進行垃圾收集時,必須暫停其他所有的工作執行緒,直到它收集結束。就是所謂的“Stop The World。”

ParNew收集器

ParNew收集器其實就是Serial收集器的多執行緒版本。除了使用多執行緒進行垃圾收集外,其餘行為包括Serial收集器可用的所有控制引數、收集演算法(複製演算法)、Stop The World、物件分配規則、回收策略等與Serial收集器完全相同,兩者共用了相當多的程式碼。

Parallel Scavenge收集器

Parallel Scavenge收集器是一個新生代蒐集器,主要採用複製演算法,與ParNew類似。但關注點與其他蒐集器不同,目標是達到一個可控的吞吐量。

Serial Old收集器

Serial Old是Serial收集器的老年代版本,同樣是一個單執行緒收集器,使用標記-整理演算法。運作圖同Serial蒐集器。

Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,使用多執行緒和“標記-整理”演算法。在JDK 1.6中才開始提供。

CMS收集器

CMS(Concurrent Mark and Sweep 併發-標記-清除),是一種以獲取最短回收停頓時間為目標的收集器。基於併發、使用標記清除演算法,只針對老年代進行垃圾回收。

CMS收集器工作時,儘可能讓GC執行緒和使用者執行緒併發執行,以達到降低STW時間的目的。

整個操作步驟分為四步:初始標記(CMS initial mark)、併發標記(CMS concurrent mark)、重新標記(CMS remark)、併發清除(CMS concurrent sweep)。

在上圖過程中,初始標記和重新標記都會觸發“Stop The World”。

初始標記僅僅只是標記一下GC Roots能直接關聯到的物件,速度很快,在Java7中是單執行緒,在Java8以後可採用多執行緒。

發標記階段GC執行緒和應用執行緒併發執行,初始標記出來的存活物件,然後繼續遞迴標記這些物件可達的物件。

重新標記階段則是為了修正併發標記期間,因使用者程式繼續運作而導致標記產生變動的那一部分物件的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長一些,但遠比並發標記的時間短。

優點:併發收集、低停頓。

缺點:對CPU資源非常敏感、無法處理浮動垃圾、標記-清除演算法導致的空間碎片。

G1收集器

G1(Garbage-First)是一款面向服務端應用的垃圾收集器。支援新生代和老年代空間的垃圾收集。

該收集器可充分利用CPU和硬體縮短STW的時間,還具有“整合空間”、“可預測停頓”等特點。比如,可建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為N毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒。

使用G1收集器時,Java堆的記憶體佈局與其他收集器有很大差別,它將整個Java堆劃分為多個大小相等的獨立區域(Region),雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔閡了,它們都是一部分(可以不連續)Region的集合。

G1會跟蹤各個Region裡面的垃圾堆積的價值大小(回收所獲得的空間大小以及回收所需時間的經驗值),在後臺維護一個優先列表,每次根據允許的收集時間,優先回收價值最大的Region(這也就是Garbage-First名稱的來由)。

G1收集器的運作大致可劃分為以下幾個步驟:初始標記(Initial Marking)、併發標記(Concurrent Marking)、最終標記(Final Marking)、篩選回收(Live Data Counting and Evacuation)。

整個流程來看,前幾個步驟與CMS的流程很相似。同樣的在初始標記和最終標記的過程中都會觸發“Stop The World”。

其中,篩選回收階段其實也可以做到與使用者程式一起併發執行,但是因為只回收一部分Region,時間是使用者可控制的,而且停頓使用者執行緒將大幅度提高收集效率。

ZGC收集器

ZGC(Z Garbage Collector),是一款可伸縮、低延遲、併發垃圾回收器。在Java11中引入,應用Linux64位系統。

其旨在實現以下幾個目標:停頓時間不超過10ms、停頓時間不隨heap大小或存活物件大小增大而增大、可以處理從幾百兆到幾T的記憶體大小。

ZGC將記憶體劃分為多個區域,也稱為ZPage。ZPages可以動態建立和銷燬。它們也可以動態調整大小(與G1 GC不同),是2 MB的倍數。以下是堆區域的大小組:Small (2 MB)、Medium (32 MB)、Large (N * 2 MB)。

ZGC堆可以多次出現這些堆區域。中型和大型區域是連續分配的,如下圖所示:

與其他GC不同,ZGC的物理堆區域可以對映到更大的堆地址空間(其中可以包括虛擬記憶體)。

ZGC的執行過程包括:標記(初始標記、併發標記、邊緣情況處理)、重新定位(查詢重新定位塊、根引用重新定位並更新、併發定位其他物件並存儲新舊地址對映)、重新對映。

其中標記中的初始標記和邊緣情況處理會引發“Stop The World”,重新定位中的“根引用重新定位並更新”也會引發“Stop The World”。

其中重新對映流程圖如下:

ZGC打算以較短的應用程式暫停時間來支援大堆大小。為了實現此目標,它使用了包括彩色64位指標,負載屏障,重定位和重新對映的技術。

小結

本文介紹了場景的垃圾收集器以及相關的概念,屬於較深層次的內容,針對這些內容還可以進一步進行橫向或縱向拓展。

有朋友在評論區問,學這些有底層什麼用?當然我們不僅僅是為了面試,就拿關於JVM結構及Java8 JVM記憶體結構變動來說吧。

昨天在部署一個比較大的專案時就出現“java.lang.OutOfMemoryError: Metaspace”異常,如果學習了之前的相關內容可以很輕易的定位到是因為JVM設定了Metaspace的上限引數,並且引數值設定小導致的。

最後,《面試官系列》正在持續更新,歡迎關注公眾號“程式新視界”,獲得最新內容。

原文連結:《面試官,不要再問我“Java 垃圾收集器”了》

《面試官》系列文章:

  • 《JVM之記憶體結構詳解》
  • 《面試官,不要再問我“Java GC垃圾回收機制”了》
  • 《面試官,Java8 JVM記憶體結構變了,永久代到元空間》
  • 《面試官,不要再問我“Java 垃圾收集器”了》


程式新視界:精彩和成長都不容錯過

相關推薦

面試不要Java 垃圾收集

如果Java虛擬機器中標記清除演算法、標記整理演算法、複製演算法、分代演算法這些屬於GC收集演算法中的方法論,那麼“GC收集器”則是這些方法論的具體實現。 在面試過程中這個深度的問題涉及的比較少,但對於理解上面的這些演算法有很好的幫助。如果能夠如數家珍,也是面試中的加分項,還是那句話,畢竟面試官的時間也不多了

面試不要Java GC垃圾回收機制”

Java GC垃圾回收幾乎是面試必問的JVM問題之一,本篇文章帶領大家瞭解Java GC的底層原理,圖文並茂,突破學習及面試瓶頸。 楔子-JVM記憶體結構補充 在上篇《JVM之記憶體結構詳解》中有些內容我們沒有講,本篇結合垃圾回收機制來一起學習。還記得JVM中堆的結構圖嗎? 圖中展示了堆中三個區域:Ede

面試不要三次握手和四次揮手

三次握手和四次揮手是各個公司常見的考點,也具有一定的水平區分度,也被一些面試官作為熱身題。很多小夥伴說這個問題剛開始回答的挺好,但是後面越回答越冒冷汗,最後就歇菜了。 見過比較典型的面試場景是這樣的: 面試官:請介紹下三次握手 求職者:第一次握手就是客戶端給伺服器端傳送一個報文,第二次就是伺服器收到報文之後

拜託不要執行緒池啦!

Java提供了幾種便捷的方法建立執行緒池,通過這些內建的api就能夠很輕鬆的建立執行緒池。在`java.util.concurrent`包中的`Executors`類,其中的靜態方法就是用來建立執行緒池的: * newFixedThreadPool():建立一個固定執行緒數量的執行緒池,而且執行緒池中的任務

拜託什麼是 B+ 樹

前言 每當我們執行某個 SQL 發現很慢時,都會下意識地反應是否加了索引,那麼大家是否有想過加了索引為啥會使資料查詢更快呢,索引的底層一般又是用什麼結構儲存的呢,相信大家看了標題已經有答案了,沒錯!B+樹!那麼它相對於一般的連結串列,雜湊等有何不同,為何多數儲存引擎都使用它呢,今天我就來揭開 B+ 樹的面紗,

Java架構-拜託面試不要Redis分散式鎖的實現原理

一、寫在前面 現在面試,一般都會聊聊分散式系統這塊的東西。通常面試官都會從服務框架(Spring Cloud、Dubbo)聊起,一路聊到分散式事務、分散式鎖、ZooKeeper等知識。 所以咱們這篇文章就來聊聊分散式鎖這塊知識,具體的來看看Redis分散式鎖的實現原理。 說實

拜託面試不要TCC分散式事務的實現原理!

往期文章 1、 拜託!面試請不要再問我Spring Cloud底層原理 2、 【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問? 3、 【效能優化之道】每秒上萬併發下的Spring Cloud引數優化實戰 4、 微服務架構如何保障

拜託面試不要Redis分散式鎖的實現原理!【石杉的架構筆記】

歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100) 週一至五早8點半!精品技術文章準時送上! 目錄 一、寫在前面 二、Redisson實現Redis分散式鎖的底層原理       (1)加鎖機制       (2)鎖互斥機制  

拜託面試不要Redis分散式鎖的實現原理!

目錄 一、寫在前面 二、Redisson實現Redis分散式鎖的底層原理       (1)加鎖機制       (2)鎖互斥機制       (3)watch dog自動延期機制   &nbs

面試求你TCP的三次握手和四次揮手

少點程式碼,多點頭髮 本文已經收錄至我的GitHub,歡迎大家踴躍star 和 issues。 https://github.com/midou-tech/articles 三次握手建立連結,四次揮手斷開連結。這個問題算非常經典的問題,也是面試官非常喜歡問的問題。 不誇張的說,龍叔在校招面試的時候每一家公

拜託!面試不要Spring Cloud底層原理

歡迎關注微信公眾號:石杉的架構筆記(id:shishan100) 每週一三五,精品技術文章準時送上! 目錄 一、業務場景介紹 二、Spring Cloud核心元件:Eureka 三、Spring Cloud核心元件:Feign 四、Spring Cloud核心元件:Ribbon 五、Sp

面試不要Spring Cloud底層原理

概述 毫無疑問,Spring Cloud是目前微服務架構領域的翹楚,無數的書籍部落格都在講解這個技術。不過大多數講解還停留在對Spring Cloud功能使用的層面,其底層的很多原理,很多人可能並不知曉。因此本文將通過大量的手繪圖,給大家談談Spring Cloud微服務架構的底層原理。實際上,Spring

SpringCloud-拜託!面試不要Spring Cloud底層原理實戰

上一篇我們說到《拜託!面試請不要再問我Spring Cloud底層原理》,我們大概瞭解了Spring Cloud中各個元件的作用以及其背後實現的原理。但是俗話說得好,實踐是檢驗真理的唯一標準。這一篇我們動手實踐一下,即搭建一個包含訂單服務、庫存服務、倉庫服務、積分服務的微服務架構專案。 一、

SpringCloud-拜託!面試不要Spring Cloud底層原理

原文地址:https://mp.weixin.qq.com/s/mOk0KuEWQUiugyRA3-FXwg,原創作者:中華石杉,微信公眾號:石杉的架構筆記。 一、概述 毫無疑問,Spring Cloud是目前微服務架構領域的翹楚,無數的書籍部落格都在講解這個技術。不過大多數講解還停留在對S

拜托面試堆(排序)

哪些 qrc 很多 適合 每次 一個 查看 怎樣 特殊 何為堆? 堆是一種特殊的樹,只要滿足下面兩個條件,它就是一個堆: (1)堆是一顆完全二叉樹; (2)堆中某個節點的值總是不大於(或不小於)其父節點的值。 其中,我們把根節點最大的堆叫做大頂堆,根節點最小的堆叫做小頂堆。

嘿嘿就知道面試接下來要 ConcurrentHashMap 底層原理怎麼秀他

前言 上篇文章介紹了 HashMap 原始碼後,在部落格平臺廣受好評,讓本來己經不打算更新這個系列的我,彷彿被打了一頓雞血。真的,被讀者認可的感覺,就是這麼奇妙。 然後,有讀者希望我能出一版 ConcurrentHashMap 的解析。所以,今天的這篇文章,我準備講述一下 ConcurrentHashMa

【終結篇】不要程序員該如何提高……

互聯 還要 了解 但是 這就是 指揮 容易 程序 自己 已經工作了的程序員該如何提高自己?我看到過很多說法,包括但不限於: 多讀書,然後各種書單,技術的、管理的,情商的、智商的,文學的、藝術的…… 鍛煉健身,身體是革命的本錢嘛! 寫博客,這個@dudu應該最喜歡了 多交朋

驀然回首陸茜文已把勾住不是想找個賢內助只渴望心靈的歸宿奈何他物件把吼住勾引之事緣起在對方處不要勾住就此打住。

2014 臺灣高考滿分作文 問世間情為何物, 汽車渴望公路, 花草渴望雨露, 靈魂渴望超度, 心靈渴望歸宿, 而我則~ 迫切渴望著有個媳婦。 眾裡尋她千百度, 踏平腳下路, 驀然回首細環顧, 大嬸大娘無數。 都說男兒有淚不撲簌, 但那絕對是未到

不要Python2和Python3的Unicode 問題啦!

寫在之前 字元編碼問題幾乎是會跟隨我們整個程式設計生涯的一大魔障,一不小心各種玄學的問題就會接踵而至,防不勝防,尤其是對初學者來說,碰到編碼問題簡直是就是加快了踏上從入門到放棄的傳送帶。 字符集問題 很多時候在使用 Python 程式設計的時候,如果不使用 Unicode,處理中文

拜託!請不要Spring Cloud底層原理

目錄 一、業務場景介紹 二、Spring Cloud核心元件:Eureka 三、Spring Cloud核心元件:Feign 四、Spring Cloud核心元件:Ribbon 五、Spring Cloud核心元件:Hystrix 六、Spring Cloud核心