1. 程式人生 > >面試官,不要再問我“Java GC垃圾回收機制”了

面試官,不要再問我“Java GC垃圾回收機制”了

Java GC垃圾回收幾乎是面試必問的JVM問題之一,本篇文章帶領大家瞭解Java GC的底層原理,圖文並茂,突破學習及面試瓶頸。

楔子-JVM記憶體結構補充

在上篇《JVM之記憶體結構詳解》中有些內容我們沒有講,本篇結合垃圾回收機制來一起學習。還記得JVM中堆的結構圖嗎?

圖中展示了堆中三個區域:Eden、From Survivor、To Survivor。從圖中可以也可以看到它們的大小比例,準確來說是:8:1:1。為什麼要這樣設計呢,本篇文章後續會給出解答,還是根據垃圾回收的具體情況來設計的。

還記得在設定JVM時,常用的類似-Xms和-Xmx等引數嗎?對的它們就是用來說設定堆中各區域的大小的。


(圖片來源於網路)

控制引數詳解:

  • -Xms設定堆的最小空間大小。
  • -Xmx設定堆的最大空間大小。
  • -Xmn堆中新生代初始及最大大小(NewSize和MaxNewSize為其細化)。
  • -XX:NewSize設定新生代最小空間大小。
  • -XX:MaxNewSize設定新生代最大空間大小。
  • -XX:PermSize設定永久代最小空間大小。
  • -XX:MaxPermSize設定永久代最大空間大小。
  • -Xss設定每個執行緒的堆疊大小。

對照上面兩個圖,再來看這些引數是不是沒有之前那麼枯燥了,它們在圖中都有了對應的位置。

有沒有發現沒有直接設定老年代空間大小的引數?我們通過簡單的計算獲得。

老年代空間大小=堆空間大小-年輕代大空間大小

對上面引數立即了,但記憶有困難?那麼,以下幾個助記詞可能更好的幫你記憶和理解引數的含義。

Xmx(memory maximum), Xms(memory startup), Xmn(memory nursery/new), Xss(stack size)。

對於引數的格式可以這樣理解:

  • -: 標準VM選項,VM規範的選項。
  • -X: 非標準VM選項,不保證所有VM支援。
  • -XX: 高階選項,高階特性,但屬於不穩定的選項。

GC概述

垃圾收集(Garbage Collection)通常被稱為“GC”,由虛擬機器“自動化”完成垃圾回收工作。

思考一個問題,既然GC會自動回收,開發人員為什麼要學習GC和記憶體分配呢?為了能夠配置上面的引數配置?引數配置又是為了什麼?

“當需要排查各種記憶體溢位,記憶體洩露問題時,當垃圾成為系統達到更高併發量的瓶頸時,我們就需要對GC的自動回收實施必要的監控和調節。”

JVM中程式計數器、虛擬機器棧、本地方法棧3個區域隨執行緒而生隨執行緒而滅。棧幀隨著方法的進入和退出做入棧和出棧操作,實現了自動的記憶體清理。它們的記憶體分配和回收都具有確定性。

因此,GC垃圾回收主要集中在堆和方法區,在程式執行期間,這部分記憶體的分配和使用都是動態的。

下面通過概念和具體的演算法來了解GC垃圾回收的過程。

如何判斷物件存活

判斷物件常規有兩種方法:引用計數演算法和可達性分析演算法(Reachability Analysis)。

引用計數演算法:給物件新增一個引用計數器,每當有一個地方引用它時計數器加1,引用釋放時計數減1,當計數器為0時可以回收。

引用計數演算法實現簡單,判斷高效,在微軟COM和Python語言等被廣泛使用,但在主流的Java虛擬機器中沒有使用該方法,主要是因為無法解決物件相互迴圈引用的問題。

可達性分析演算法:基本思想是通過一系列稱為“GC Root”的物件(如系統類載入器、棧中的物件、處於啟用狀態的執行緒等)作為起點,基於物件引用關係,開始向下搜尋,所走過的路徑稱為引用鏈,當一個物件到GC Root沒有任何引用鏈相連,證明物件是不可用的。

上圖中中綠色部分為存活物件,灰色部分為可回收物件。雖然灰色部分內部依舊有關聯,但它們到GC Root是不可達的。

面試問題

面試官,說說Java GC都用了哪些演算法?分別應用在什麼地方?

答:複製演算法、標記清除、標記整理……

你還在單純的死記硬背麼?繼續往下看,你會豁然開朗,再也不用死記硬背了。

標記清除演算法

標記清除(Mark-Sweep)演算法,包含“標記”和“清除”兩個階段:首先標記出所有需要回收的物件,在標記完成後統一回收掉所有被標記的物件。

標記清除演算法是最基礎的收集演算法,後續的收集演算法都是基於該思路並對其缺點進行改進而得到的。

主要缺點:一個是效率問題,標記和清除過程的效率都不高;另外是空間問題,標記清除之後會產生大量不連續的記憶體碎片,空間碎片太多可能會導致,當程式在以後的執行過程中需要分配較大物件時無法找到足夠的連續記憶體而不得不提前觸發另一次垃圾收集動作。

複製演算法

複製(Copying)演算法:將可用記憶體按容量劃分為大小相等的兩塊,每次只使用其中的一塊。當一塊記憶體用完了,就將還存活著的物件複製到另外一塊上,然後清理掉前一塊。

每次對半區記憶體回收時、記憶體分配時就不用考慮記憶體碎片等複雜情況,只要移動堆頂指標,按順序分配記憶體即可,實現簡單,執行高效。

缺點:將記憶體縮小為一半,價效比低,持續複製長生存期的物件則導致效率低下。

JVM堆中新生代便採用複製演算法。回到最初推分配結構圖。

在GC回收過程中,當Eden區滿時,還存活的物件會被複制到其中一個Survivor區;當回收時,會將Eden和使用的Survivor區還存活的物件,複製到另外一個Survivor區,然後對Eden和用過的Survivor區進行清理。

如果另外一個Survivor區沒有足夠的記憶體儲存時,則會進入老年代。

這裡針對哪些物件會進入老年代有這樣的機制:物件每經歷一次複製,年齡加1,達到晉升年齡閾值後,轉移到老年代。

在這整個過程中,由於Eden中的物件屬於像浮萍一樣“瞬生瞬滅”的物件,所以並不需要1:1的比例來分配記憶體,而是採用了8:1:1的比例來分配。

而針對那些像“水熊蟲”一樣,歷經多次清理依舊存活的物件,則會進入老年代,而老年的清理演算法則採用下面要講到的“標記整理演算法”。

標記整理演算法

標記整理(Mark-Compact)演算法:標記過程與“標記-清除”演算法一樣,但後續步驟不是直接對可回收物件進行清理,而是讓所有存活的物件都向一端移動,然後直接清理掉端邊界以外的記憶體。

這種演算法不既不用浪費50%的記憶體,也解決了複製演算法在物件存活率較高時的效率低下問題。

分代收集演算法

分代收集演算法,基本思路:將Java的堆記憶體邏輯上分成兩塊,新生代和老年代,針對不同存活週期、不同大小的物件採取不同的垃圾回收策略。

而在新生代中大多數物件都是瞬間物件,只有少量物件存活,複製較少物件即可完成清理,因此採用複製演算法。而針對老年代中的物件,存活率較高,又沒有額外的擔保記憶體,因此採用標記整理演算法。

其實,回頭看,分代收集演算法就是對新生代和老年代演算法從策略維度的規劃而已。

小結

至此,當面試官再問Java GC都用到了哪些垃圾回收演算法和分別應用在什麼場景下的問題,再也不用死記硬背了吧?

關於Java GC還有垃圾收集器及垃圾回收調優,我們將在後續文章中持續更新,歡迎關注公眾號“程式新視界”獲得第一手更新。

原文連結:《面試官,不要再問我“Java GC垃圾回收機制”了》
系列文章:《JVM之記憶體結構詳解》

參考資料:《深入理解java虛擬機器》。


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

相關推薦

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

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

面試不要Java 垃圾收集器”

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

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

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

拜託不要執行緒池啦!

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

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

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

拜託!不要是否瞭解多執行緒好嗎

  面試過程中,各面試官一般都會教科書式的問你幾個多執行緒的問題,但又不知從何問起。於是就來一句,你瞭解多執行緒嗎?拜託,這個有好傷自尊的!   相信老司機們對於java的多執行緒問題處理,穩如老狗了。你問我瞭解不?都懶得理你。   不過,既然是面對的是面試官,那你還得一一說來。   今天我們就從多個角度來領

求你Zookeeper如何實現分散式鎖!!!

導讀 真是有人(鎖)的地方就有江湖(事務),今天不談江湖,來撩撩人。 分散式鎖的概念、為什麼使用分散式鎖,想必大家已經很清楚了。前段時間作者寫過Redis是如何實現分散式鎖,今天這篇文章來談談Zookeeper是如何實現分散式鎖的。 陳某今天分別從如下幾個方面來詳細講講ZK如何實現分散式鎖:

不要MVC、MVP、MVVM

網路上有很多類似的討論。比如 阮一峰:MVC,MVP 和 MVVM 的圖示 廖雪峰:MVVM 司徒正美: 各自用一句話來概括MVC、MVP、MVVM的差異特點 。。。 但是說的往往比較概念化、空泛,初學者很難理解。本篇用最簡單的例子講解這三者,看完本篇,你就不會再糾結這個問題了   框架的起源與目的

轉發Java GC - 垃圾回收機制

devel 時間段 first 並行 不能 lean com ring 更新 1、簡介 對於Java developer來說,了解JVM GC工作原理能夠幫助我們開發出更優秀的應用,同時在處理JVM瓶頸時能夠更加自由。在最近一年的應用開發中能體會到這些知識帶來的好處

Android內存優化1 java GC 垃圾回收機制3

速度 一個 這就是 並發 mod class 授權 回收 collector 引言 接App優化之內存優化(序), 作為App優化系列中內存優化的一個小部分. 由於內存相關知識比較生澀, 內存優化中使用到的相關工具, 也有很多專有名詞. 對Java內存管理, GC, A

JAVA gc垃圾回收機制

一、GC概要   JVM堆相關知識     為什麼先說JVM堆?     JVM的堆是Java物件的活動空間,程式中的類的物件從中分配空間,其儲存著正在執行著的應用程式用到的所有物件。這些物件的建立方式就是那些new一類的操作,當物件無用後,是GC來負責這個無用的物件(地球人都知道)。 JVM堆     (

JAVA GC垃圾回收機制簡單易懂的理解

一、什麼是垃圾回收機制? JAVA語言的一個顯著特點是垃圾回收機制,相比C++而言,程式設計師不需要關心繁瑣的記憶體管理問題。 所以,簡單的說,垃圾回收機制就是JVM利用一些列演算法對記憶體進行管理,包括記憶體的分配與回收。   二、垃圾回收機制的原理是什麼呢? 其實垃

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中各個元件的作用以及其背後實現的原理。但是俗話說得好,實踐是檢驗真理的唯一標準。這一篇我們動手實踐一下,即搭建一個包含訂單服務、庫存服務、倉庫服務、積分服務的微服務架構專案。 一、