自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官問我JVM的GC分代收集算法為什么這么設(shè)計(jì)

開發(fā) 前端
目前面試比較常問的垃圾回收算法就是這幾種,我們分開來說,最后說說分代收集為什么選擇不同的算法來實(shí)現(xiàn)。

最近阿粉的小學(xué)妹,給阿粉留言,說面試官不按套路出牌,問JVM的相關(guān)知識的時(shí)候,不問有什么GC算法,而是問我為什么這么設(shè)計(jì),讓學(xué)妹很懵圈,阿粉就差給小學(xué)妹的腦殼敲破了,面試官這么問,只是考驗(yàn)?zāi)?,知其然,知其所以然么?今天阿粉就來簡單的說說這個(gè)。

JVM 的垃圾回收機(jī)制

我們先來說說這個(gè)回收機(jī)制的算法都有哪些,如圖所示。

圖片

目前面試比較常問的垃圾回收算法就是這幾種,我們分開來說,最后說說分代收集為什么選擇不同的算法來實(shí)現(xiàn)。

標(biāo)記清除算法 Mark-Sweep

我們都知道,標(biāo)記清除算法,是垃圾回收算法當(dāng)中算是最基礎(chǔ)的算法了,因?yàn)闃?biāo)記算法就只有兩個(gè)階段,

  • 階段一 標(biāo)記
  • 階段二 清除

標(biāo)記的是什么內(nèi)容呢?

標(biāo)記的都是所有的需要被回收的對象,當(dāng)執(zhí)行到清除階段的時(shí)候,就會(huì)直接把這些標(biāo)記的對象給完整的清除掉。

圖片

如果是這樣的話,那么就會(huì)出現(xiàn)了一個(gè)問題,大家看,如果灰色的是我們的內(nèi)存空間,然后我們把需要把被回收的對象清除的話,我們不能保證這個(gè)被回收的對象,一定會(huì)是連續(xù)排在一起的,就比如所有需要被回收的對象,都排在最上面的內(nèi)存空間中,這個(gè)是不太可能的,所以,執(zhí)行完清除之后,這些未使用的內(nèi)存空間,就成了一個(gè)不連續(xù)的內(nèi)存空間。

標(biāo)記清除算法,最大的弊端出現(xiàn)了,碎片化就非常的嚴(yán)重,如果有大對象想要存入,而內(nèi)存中出現(xiàn)沒有連續(xù)空間的話,那他就沒有可用空間保存了。

為了解決碎片化嚴(yán)重的這種情況,就有了下面的這種垃圾回收算法。

復(fù)制算法(copying)

為了解決這個(gè)內(nèi)存碎片化嚴(yán)重的問題,按內(nèi)存容量將內(nèi)存劃分為等大小的兩塊。每次只使用其中一塊,當(dāng)這一塊內(nèi)存滿后將尚存活的對象復(fù)制到另一塊上去,把已使用的內(nèi)存清掉。

圖片

實(shí)際上,這種方式大家看起來,有沒有什么問題呢?解決了碎片化嚴(yán)重的情況,但是他把內(nèi)存空間,直接劃分成了相等的兩塊,如果我們目前需要被回收的對象比較少,存活的對象比較多的話,那么這種復(fù)制算法的效率,真的是有點(diǎn)低了。

那么有沒有一個(gè)折中的呢?

這就出現(xiàn)了另外一個(gè)算法,

標(biāo)記整理算法(Mark-Compact)

這種算法比較特殊了,標(biāo)記階段和 Mark-Sweep 算法相同,但是整理的時(shí)候,就不一樣了,標(biāo)記后不是清理對象,而是將存活對象移向內(nèi)存的一端。然后清除端邊界外的對象。也就是,有可能是存活對象被移到左邊,然后右邊是需要被清理的對象,

圖片

這樣既能保證了內(nèi)存空間是連續(xù)的,而且還能讓效率提升。

那么我們可以回歸這個(gè)標(biāo)題了,GC分代收集,為什么這么設(shè)計(jì)。

分代

這個(gè)就挺好理解的,畢竟都知道一個(gè)共同的知識點(diǎn),那就是 GC堆內(nèi)存分為了老年代和新生代。

如果要選擇算法,那么一定得從他們的本質(zhì)去入手。

老年代:存活數(shù)量多,需要被處理的對象少

新生代:存活數(shù)量少,需要被處理的對象多

這種從本質(zhì)的區(qū)別就劃分出來了,一個(gè)存活對象多,一個(gè)存活對象少,一個(gè)需要被清理的對象多,一個(gè)需要被清理的對象少。

復(fù)制算法因?yàn)槊看螐?fù)制的都是存活的對象,而新生代的存活對象都是比較少的,所以這個(gè)時(shí)候就可以采用復(fù)制算法來實(shí)現(xiàn)。

也就是說,新生代中劃分出來的大Eden 區(qū) 和兩個(gè) Survivor區(qū),每次使用的時(shí)候都是 Eden 區(qū)和其中的一塊 Survivor 區(qū),當(dāng)進(jìn)行回收時(shí),將該兩塊空間中還存活的對象復(fù)制到另一塊 Survivor 區(qū)中。

所以因?yàn)樾律倪@種特性,所以使用復(fù)制算法。

而老年代因?yàn)槊看沃换厥丈倭繉ο?,因而采?Mark-Compact 算法。

這就是為什么面試的時(shí)候,面試官會(huì)問你為什么GC分代收集時(shí)選擇不同算法的原因。

JVM的垃圾收集器

圖片

一般面試很多都是執(zhí)著于去問垃圾回收機(jī)制和算法,很少有涉及到JVM的垃圾收集器的,阿粉今天稍微科普一下這個(gè)小知識。

Serial 收集器(新生代)

最早的收集器

采用復(fù)制算法,暫停所有用戶線程,

特點(diǎn)是簡單高效并且是單線程,但是容易導(dǎo)致全局停頓,就是我們經(jīng)常所說的 STW(全局暫停)。

STW:

全局停頓,Java 代碼停止運(yùn)行,native 代碼繼續(xù)運(yùn)行,但不能與 JVM 進(jìn)行交互

ParNew收集器(新生代)

實(shí)際上屬于 Serial 收集器 的升級版,從單線程變成了多線程,算法一樣,也是暫停所有用戶線程。

主要用來搭配 CMS 收集器一起使用。

Parallel Scavenge收集器(新生代)

吞吐量收集器,這個(gè)收集器關(guān)注的是吞吐量

在 JVM 中有參數(shù)可以配置

  • -XX:MaxGCPauseMillis:控制最大的垃圾收集停頓時(shí)間
  • -XX:GCTimeRatio:設(shè)置吞吐量的大小,取值 0-100, 系統(tǒng)花費(fèi)不超過 1/(1+n) 的時(shí)間用于垃圾收集

Serial Old 收集器(老年代)

老年代的收集器,采用標(biāo)記-整理算法

CMS 收集器(老年代)

算法采用標(biāo)記-清除算法實(shí)現(xiàn),

一般這個(gè)面試問的可能比較多,因?yàn)樗鼘儆诓l(fā)的收集器,因?yàn)樗⒉粫?huì)像前面說的那些收集器一樣,會(huì)直接導(dǎo)致所有用戶線程停止,直到清除結(jié)束,而是在標(biāo)記過程中會(huì)有短暫的停止。

而是先進(jìn)行初始標(biāo)記,然后進(jìn)行并發(fā)標(biāo)記,修正并發(fā)標(biāo)記用以進(jìn)行重新標(biāo)記,最后進(jìn)行并發(fā)清除。

G1 收集器

G1(Garbage-First)收集器將堆內(nèi)存分割成不同的區(qū)域,然后并發(fā)的對其進(jìn)行垃圾回收。G1收集器的設(shè)計(jì)目標(biāo)是取代CMS收集器,它同CMS相比,不會(huì)產(chǎn)生大量內(nèi)存碎片,并可以添加預(yù)測機(jī)制,用戶可以指定期望停頓時(shí)間(可通過配置-XX:MaxGCPauseMills=n最大停頓時(shí)間)

收集演示圖:

圖片

說這些,最重要的卻是,如何選擇合適的垃圾收集器

組合選擇:

  • 單CPU或小內(nèi)存,單機(jī)程序 -XX:+UseSerialGC
  • 多CPU,需要最大吞吐量,如后臺計(jì)算型應(yīng)用 -XX:+UseParallelGC或者 -XX:+UseParallelOldGC
  • 多CPU,追求低停頓時(shí)間,需快速響應(yīng)如互聯(lián)網(wǎng)應(yīng)用 -XX:+UseConcMarkSweepGC -XX:+ParNewGC

以上就是阿粉給大家?guī)淼年P(guān)于面試中的JVM 的一些小小的知識點(diǎn)了,有興趣的可以繼續(xù)深入了解關(guān)于 JVM 的知識,這樣大家就能保證在面試的時(shí)候被面試官換個(gè)問法就不會(huì)的情況了。

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2021-11-15 09:32:06

浮點(diǎn)面試Java

2021-12-02 08:19:06

MVCC面試數(shù)據(jù)庫

2021-06-03 08:55:54

分布式事務(wù)ACID

2022-05-24 08:03:28

InnoDBMySQL數(shù)據(jù)

2021-02-19 10:02:57

HTTPSJava安全

2022-07-06 13:48:24

RedisSentinel機(jī)制

2024-02-04 10:29:58

線程通信

2023-12-07 12:21:04

GCJVM垃圾

2021-05-19 08:17:35

秒殺場景高并發(fā)

2023-12-06 09:10:28

JWT微服務(wù)

2021-05-20 08:54:16

Go面向對象

2020-04-16 08:22:11

HTTPS加解密協(xié)議

2010-08-23 15:06:52

發(fā)問

2020-10-24 15:50:54

Java值傳遞代碼

2021-01-21 07:53:29

面試官Promis打印e

2021-05-11 21:56:11

算法清除JVM

2021-10-25 08:49:32

索引數(shù)據(jù)庫MySQL

2022-12-27 08:39:54

MySQL主鍵索引

2017-09-21 14:40:06

jvm算法收集器

2021-12-20 10:30:33

forforEach前端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號