看了這些,你還能說你不理解GC原理根资?

引用有哪些類型架专?

強引用:通過new創(chuàng)建出來的對象。只要強引用存在玄帕,垃圾回收器將不會回收部脚。
軟引用:通過SoftReference實現(xiàn)軟引用,系統(tǒng)將要發(fā)生內(nèi)存溢出之前才會對這些對象進行回收裤纹。
弱引用:通過WeakReference實現(xiàn)弱引用委刘,無論當內(nèi)存足夠丧没,GC運行時都會進行回收。
虛引用:通過PhantomReference實現(xiàn)锡移,通過虛引用無法回去對象的實例呕童,虛引用的作用就是當此對象被回收時,會收到一個系統(tǒng)通知淆珊。

如何判斷一個對象是否應該被回收夺饲?

1、引用計數(shù)算法施符,每當有一個地方引用他往声,就加1,引用失效戳吝,就減1.數(shù)量為0浩销,說明可以進行回收。
引用計數(shù)算法的缺點就是無法判斷兩個對象之間存在相互引用的情況听哭。
jvm中沒有使用這種判斷方式
2慢洋、可達性分析算法,通過一系列GCRoot對象作為起始點陆盘,從這些點開始向下搜索普筹,搜索的路徑成為引用鏈,當一個對象到GC沒有任何引用鏈礁遣,說明對象可以被回收斑芜。

GCRoot對象有哪些肩刃?

(1)虛擬機棧的棧幀中引用的對象祟霍。
(2)方法區(qū)中靜態(tài)屬性引用的對象。
(3)方法區(qū)中常亮引用的對象盈包。
(4)本地方法棧中jni引用的對象沸呐。
枚舉根節(jié)點時候需要GC停頓,保證分析結(jié)果的準確性呢燥。

使用GCRoot枚舉根節(jié)點崭添,由于在整個方法區(qū)進行枚舉會耗費時間。如何解決叛氨?

執(zhí)行準確式GC并不需要檢查執(zhí)行上下文中所有的引用的位置呼渣,在Hotspor中通過OopMap的數(shù)據(jù)結(jié)構(gòu)來達到這個目的。在類加載完成的時候寞埠,虛擬機會將對象內(nèi)什么偏移量什么數(shù)據(jù)計算出來屁置,在JIT編譯的時候,會在特定的位置記住棧和寄存器中什么地方存在引用仁连,GC直接對這些引用進行掃描蓝角。

什么是安全點?

OopMap雖然可以進行快速準確的進行GC Root枚舉,但是由于虛擬機的指令太多使鹅,如果為每個指令都生成對應的OopMap會浪費大量的空間揪阶,所以虛擬機會在特定的位置生成OopMap,這些特定的位置稱作安全點患朱。所以程序不是在任何時候都能夠進行GC,只有到達安全點才能進行GC裁厅。

安全點如何選定倦淀?

依據(jù)是否能夠讓程序長時間的運行為特點進行選定,由于每條指令的運行時間都十分短,所以一般選用的點為方法的調(diào)用,循環(huán)跳轉(zhuǎn)甘邀,異常跳轉(zhuǎn)等。

發(fā)生GC時需要線程停頓,如何讓線程在發(fā)生GC時候跑到最近的安全點停頓下來?

1褂傀、搶先式中斷:發(fā)生GC時中斷所有的線程,如果發(fā)現(xiàn)某條線程不在安全點,就恢復此線程讓他跑到安全點上。(虛擬機一般不使用)
2、主動式中斷:不對線程進行操作。設置一個標志位,讓所有的線程去輪詢標志位,發(fā)現(xiàn)標志位為真,就自動掛起。輪詢標志的地方和安全點是重合的鸠儿,再加上創(chuàng)建對象需要分配內(nèi)存的地方。

什么是安全區(qū)域命斧?

安全點解決了GC問題田晚,但是當發(fā)生GC的時候線程處于sleep狀態(tài),此時線程無法響應中斷請求国葬。此時需要使用安全區(qū)域進行解決贤徒。安全區(qū)域就是代碼片段中引用關(guān)系不會發(fā)生變化的地方芹壕。當線程執(zhí)行到安全區(qū)域的時候,會對線程進行標記接奈,發(fā)生GC時候踢涌,jvm不管這些線程,在GC的時候序宦,如果這些線程要離開安全區(qū)域睁壁,此時,判斷jvm是否已經(jīng)完成GC互捌,如果完成潘明,則線程執(zhí)行,如果沒有完成秕噪,則線程停頓等待GC完成的信號钳降。(當線程發(fā)生sleep時正處于安全區(qū)域)

可達性算法不可達的對象就一定會被回收嗎?

不一定腌巾,當發(fā)現(xiàn)對象不可達的時候牲阁,將會對此對象進行第一次標記,對標記的對象就行篩選壤躲,篩選的條件是是否有必要執(zhí)行finalize()方法城菊。
當此對象已經(jīng)調(diào)用過finalize()方法或者在對象中沒有覆蓋finalize()方法,則判定次對象沒有必要執(zhí)行finalize()方法碉克。
沒有必要執(zhí)行finalize()方法的對象將會直接被回收凌唬。
有必要執(zhí)行finalize()方法的對象放在一個隊列中,之后有虛擬機創(chuàng)建一個低優(yōu)先級的線程去出發(fā)隊列中的對象的finalize()方法漏麦,注意此處為觸發(fā)并非等待finalize()執(zhí)行結(jié)束客税,防止finalize()方法中出現(xiàn)死循環(huán)導致回收系統(tǒng)崩潰。
當一個對象的finalize()方法執(zhí)行結(jié)束后撕贞,方法并沒有被回收更耻,稍后會對隊列中的對象進行二次標記,此時標記的依據(jù)是對象是否可達捏膨。如果還是不可達秧均,才會將此對象放入即將回收的集合。所以finalize()方法中如果為對象添加引用鏈号涯,可以拯救此對象目胡。
注意:每個對象的finalize()方法只會被jvm調(diào)用一次,如果一個對象在第一次執(zhí)行finalize()時候被拯救链快,在下次執(zhí)行回收會直接對對象就行回收誉己,將不會調(diào)用對象的finalize()方法。

方法區(qū)中沒有垃圾回收域蜗?

方法區(qū)有垃圾回收巨双,但是回收的效率低噪猾。
方法區(qū)只要回收廢棄的常量和無用的類。
如果沒有任何地方對此常量進行引用筑累,則此常量就會被回收畏妖。

方法區(qū)中哪些類是無用的類?

(1)java堆中不存在該類的任何實例疼阔。
(2)加載該類的ClassLoader已經(jīng)被回收戒劫。
(3)該類的class對象沒有任何地方被引用。
滿足以上三個條件的類可以被回收婆廊,而不是和java堆中的對象一樣必然會被回收迅细。

對象的創(chuàng)建是如何創(chuàng)建的(new)?:

當虛擬機遇到new指令的時候淘邻,先去檢查這個指令的參數(shù)是否能夠在常量池中定位到一個符號的引用(類的全限定名)茵典,在判斷這個符號引用代表的類是否已經(jīng)被加載,如果沒有被加載宾舅,將會進行類的加載操作统阿。通過加載檢查后,將對類分配內(nèi)存筹我。

對象創(chuàng)建時內(nèi)存分配方式扶平?

1、指針碰撞蔬蕊,對象需要多大的內(nèi)存在類加載完成的時候就已經(jīng)確定结澄,此內(nèi)存分配方式相當于,將已分配的內(nèi)存放在放在一邊岸夯,為分配的內(nèi)存放在另一邊麻献,中間用指針進行隔離,當需要分配內(nèi)存的時候只需要移動指針即可猜扮。
2勉吻、空閑列表,即維護一個列表旅赢,記錄內(nèi)存中還沒有分配的內(nèi)存位置齿桃。

分配內(nèi)存的過程并非是線程安全的解決方案。

1鲜漩、失敗重試源譬。
2、為每個線程分配本地線程緩沖區(qū)(TLAB)孕似,當TLAB使用完之后分配新的TLAB的時候,實行同步鎖定刮刑。分配結(jié)束后喉祭,將分配的內(nèi)存除對象頭外养渴,其余初始化為0值。如果使用TLAB泛烙,則初始化為0值提前到TLAB分配時執(zhí)行理卑。

GC對內(nèi)存的分配。

內(nèi)存一般分為新生代和老年代蔽氨,新生代又分為一塊較大的Eden和兩塊較小的Survivor區(qū)域(HotSpot虛擬機E:S=8:1)藐唠,
新生的對象優(yōu)先分配在新生代的E區(qū),如果啟用本地線程緩沖鹉究,優(yōu)先在TLAB上進行分配宇立,少數(shù)情況也會直接在老年代進行對象的分配,當在E分配對象發(fā)現(xiàn)內(nèi)存不夠使用的時候自赔,會發(fā)生新生代的GC將E區(qū)對象轉(zhuǎn)入S區(qū)妈嘹,當發(fā)現(xiàn)S區(qū)無法存放時,通過分配擔保將對象轉(zhuǎn)入老年代绍妨。

對象進入老年代的判定润脸。

大對象直接進入老年代(閥值可以通過參數(shù)進行設定),為了避免E區(qū)和S區(qū)之間發(fā)生大量的內(nèi)存復制他去。
長期存活的對象進入老年代毙驯,虛擬機給每個對象定義了一個年齡計數(shù)器,在E區(qū)中的對象經(jīng)過一次GC仍然存活并能夠被S區(qū)容納灾测,設置此對象的年齡為1尔苦,在S區(qū)中的對象,每熬過一次GC行施,就將年齡加1允坚,當年齡達到一定的程度(默認是15,可以通過參數(shù)進行設置)就會進入老年代蛾号,
動態(tài)年齡判斷稠项,不一定只有年齡達到閥值才會進入老年代,當相同年齡的對象的總大小大于S空間的一半鲜结,則大于等于這個年齡的對象將會進入老年代展运。

什么是空間分配擔保?

當新生代發(fā)生GC的時候精刷,先判斷老年代中的剩余空間的總大小是否大于新生代中的總對象的大小拗胜,如果是,則發(fā)生進行新生代的GC怒允,如果不是埂软,則判斷是否允許擔保失敗,如果不允許纫事,則進行老年代的GC,如果允許勘畔,則判斷老年代中的剩余空間的總大小是否大于新生代每次發(fā)生GC時進入老年代的對象的平均值所灸,如果是,則進行新生代的GC炫七,如果不是爬立,則進行一次老年代的GC。

垃圾回收算法有那些万哪?

1侠驯、標記-清除:標記所有需要被回收的對象,然后回收奕巍。次算法效率低吟策,并且產(chǎn)生內(nèi)存碎片,由于老年代中存活的對象多伍绳,在老年代中進行使用踊挠。
2、復制算法:將內(nèi)存劃分為等大小的兩塊冲杀,每次使用其中的一塊效床,回收時,將存活的對象復制到?jīng)]有使用的一塊內(nèi)存中权谁,然后對使用的內(nèi)存一次性就行清理剩檀。實現(xiàn)簡單,運行高效旺芽,但是存在大量內(nèi)存的浪費沪猴。由于新生代中存活的對象少,新生代中使用這種算法將E區(qū)存活的對象復制到S區(qū)采章。
3运嗜、標記整理算法:讓所有存活的對象往一側(cè)移動,然后清楚另一側(cè)悯舟。在老年代中使用這種算法担租,避免產(chǎn)生內(nèi)存碎片。

文中有些和GC無關(guān)的知識抵怎,如對象的創(chuàng)建奋救,引用的類型等,知識為了讓讀者更好的了解GC反惕,如果有疑問可以留言隨時討論尝艘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市姿染,隨后出現(xiàn)的幾起案子背亥,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隘梨,死亡現(xiàn)場離奇詭異程癌,居然都是意外死亡舷嗡,警方通過查閱死者的電腦和手機轴猎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來进萄,“玉大人捻脖,你說我怎么就攤上這事≈惺螅” “怎么了可婶?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長援雇。 經(jīng)常有香客問我矛渴,道長,這世上最難降的妖魔是什么惫搏? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任具温,我火速辦了婚禮,結(jié)果婚禮上筐赔,老公的妹妹穿的比我還像新娘铣猩。我一直安慰自己,他們只是感情好茴丰,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布达皿。 她就那樣靜靜地躺著,像睡著了一般贿肩。 火紅的嫁衣襯著肌膚如雪峦椰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天汰规,我揣著相機與錄音汤功,去河邊找鬼。 笑死控轿,一個胖子當著我的面吹牛冤竹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播茬射,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼鹦蠕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了在抛?” 一聲冷哼從身側(cè)響起钟病,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后肠阱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體票唆,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年屹徘,在試婚紗的時候發(fā)現(xiàn)自己被綠了走趋。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡噪伊,死狀恐怖簿煌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鉴吹,我是刑警寧澤姨伟,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站豆励,受9級特大地震影響夺荒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜良蒸,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一技扼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诚啃,春花似錦淮摔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至造垛,卻和暖如春魔招,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背五辽。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工办斑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人杆逗。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓乡翅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親罪郊。 傳聞我的和親對象是個殘疾皇子蠕蚜,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 引用有哪些類型?強引用:通過new創(chuàng)建出來的對象挣柬。只要強引用存在潮酒,垃圾回收器將不會回收。軟引用:通過SoftRef...
    yeying12321閱讀 371評論 1 0
  • 1.什么是垃圾回收邪蛔? 垃圾回收(Garbage Collection)是Java虛擬機(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,503評論 17 311
  • 原文閱讀 前言 這段時間懈怠了急黎,罪過! 最近看到有同事也開始用上了微信公眾號寫博客了店溢,挺好的~給他們點贊叁熔,這博客我...
    碼農(nóng)戲碼閱讀 5,978評論 2 31
  • 一. 垃圾回收的意義 在C++中委乌,對象所占的內(nèi)存在程序結(jié)束運行之前一直被占用床牧,在明確釋放之前不能分配給其它對...
    Stan_Z閱讀 1,933評論 0 25
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡上收集的一些資料的整理,因此不免有一些不準確的地方遭贸,同時不同JDK版本的...
    高廣超閱讀 15,608評論 3 83