1. 程式人生 > >「 Offer收割機之JVM」:生存還是毀滅

「 Offer收割機之JVM」:生存還是毀滅

這兩天,廣州的天氣又開始熱了起來,又到了小動物交配的季節,啊呸,又到了一個收割 offer 的季節。年底將至,又到了面試的高峰期,JVM 作為Java 程式設計師面試繞不過的一道坎兒,它又來了,你準備好了嗎?

說說引用

面試官 A:小夥幾,上篇我們說到了 JVM 收集的兩種演算法 —— 引用記數法和可達性分析演算法,你對這兩種演算法的理解很清晰,那麼這兩種演算法有一個很重要的點,就是『引用』,其實無論是引用記數法和可達性分析演算法都離不開引用,那麼你來談談引用吧。

我: 這個啊,簡單,引用(reference)就是一塊記憶體儲存著另一塊記憶體地址(自信臉

面試官 A:說的倒也沒錯,但是過於片面,那麼你能不能詳細講一下引用呢?

我:上白板,我直接上圖吧(熟練的拿起馬克筆

面試官 A:那麼你能不能詳細的說一下這四種引用是在什麼情況下出現的呢,它們分別代表了什麼意義?

我:先說說強引用吧,我們日常中最常見到的就是強引用(拿起桌上的白板,開始手寫程式碼,就像這樣的,就屬於強引用,它有多強呢,就是隻要強引用存在,GC 永遠不會對它下手,嗯,你可以理解為就是範閒,皇上的私生子。

String s = "vi的技術部落格";
s = "技不可失";

面試官 A:你也看慶餘年啊,話說你看過原著沒,結局是什麼給我劇透劇透唄。

我:咳咳,老哥這樣不太好吧,這是我的微信:cm_950825,有什麼咱們私聊好吧,不要砸我 offer 收割機的招牌,別人還以為我是靠裙帶關係來著(小聲BB

面試官 A:那你來說一下軟引用吧。

我:我們還是接著來聊慶餘年吧,開個玩笑啦,我來一起把軟引用和弱引用一起說吧,它們都是用來描述一些非必需的物件,但是弱引用比起軟引用來說,更加的弱,怎麼說呢,還是看圖吧(揮斥方遒的感覺

軟引用關聯的物件,在系統發生 OOM之前,會把這些物件列入到回收範圍之中進行二次回收,如果這次回收仍然沒有足夠的記憶體,才會發生 OOM,它是長這樣兒式兒的。

Object o = new Object();
SoftReference<Object> soft = new SoftReference<Object>(o);

而弱引用就是個弟弟,只要有 GC,必被回收,這個弟弟是這樣的

Object o = new Object();
WeakReference<Object> weak = new WeakReference<Object>(o);

而它們的有一個普遍的應用場景:軟引用和弱引用的一個特點是它何時被回收是不可確定的, 因為這是由GC執行的不確定性所確定的. 所以, 一般用它們是有價值被快取, 而且很容易被重新被構建, 且很消耗記憶體的物件.

更深的東西我沒有再去研究了。。

面試官 A:整挺好,那你來說說最後的這個虛引用吧。

我:虛引用啊,這玩意兒你可以理解為沒有這個東西,它的唯一作用就是能在這個物件被 GC 的時候收到一個系統通知。

面試官 A:是這樣啊,那行吧,我手機沒油了,咱們下次接著聊

面試官上集手機忽然沒油了,不知道去哪加了一波油,又回來準備繼續和我大戰三百回合,尿遁用的如此熟練,一看就不是第一次幹這個事情,不是個簡單角色啊,我需要提高警惕了。

繼續面試

面試官 A :剛剛我的手機沒油了,去加了點油(挑眉

我:理解理解,那咱們繼續吧?

面試官 A:剛剛我們說到關於引用的一些知識,那麼現在有一個問題,我們最開始說到了『可達性分析法』是我們目前正在使用的一個判定方法,那麼是否沒有連線到 GC Root 的物件都是被要被 GC 回收的呢?

我:話其實也不能這麼說(捏衣角),其實還是有挽回的餘地的,大道五十,天衍四九。自然會有一絲生機,生機就在於 finalize() 這個神奇的方法中,如果虛擬機發現物件沒有連線到 GC Root 上,這個物件就會被打上一個待回收的標籤,如果對它不管不顧,它就會拋棄掉,但是如果對它進行一些操作,比如說重寫finalize()方法,在裡面對它重新進行引用,就可以對這個物件進行最後的救贖。

面試官 A:既然說到了finalize(),你來說說你對這個方法的理解吧~

我:finalize()Object類中的protected方法,我們通常在子類中繼承去完成資源清理的工作,GC 在進行回收的時候回去呼叫這個方法,但是我們通常不會用這個方法去進行GC,而是去釋放一些連線資源或者 IO流。

面試官 A:那麼我們為什麼通常不會用這個方法去完成 GC 呢?

我:原因啊。。這個我得好好想想,是這樣的,finalize()實際上並不能保證資源被回收,因為物件的finalize()方法中可以去做一些操作,使物件重新活過來,這個我剛剛也說過了,而且,由於finalize()方法只會被執行一次,會影響我們的判斷,而且它的執行效率非常低,所以我們一般不會用finalize()方法去回收物件。

面試官 A:OK,雖然有些粗略,但是大概說了出來,最後一個問題,你來梳理一下判定一個物件是否為垃圾的流程圖吧。

我:好嘞~

  1. 首先,新建一個物件,這個時候物件是處於存活狀態的。

  2. 當物件變成 GC Roots 不可達的時候,GC 會去判斷是否覆蓋了finalize()方法

  3. 如果沒有覆蓋,直接進行回收。

  4. 如果覆蓋了,再去判斷物件是否執行過finalize()方法,如果已經執行過,那麼也會進行回收。

  5. 如果覆蓋且沒有執行過finalize()方法,會將這個物件放到一個叫做 F-Queue 的佇列中去。

  6. 稍後由一個 JVM 自動建立的、低優先順序的 Finalizer 執行緒去執行

  7. 這裡需要注意:這裡的執行並不意味著真的會執行完畢,只是告知虛擬機器會觸發這個方法,並不保證可以執行完畢。

  8. 執行完畢之後,如果物件仍然沒有被重新引用(拯救),那麼就會被回收。

  9. 如果被重新引用的話,就會被「復活」了。

面試官 A:可以,講述的還算清楚,我這邊考慮一下,你先回去等通知吧

我:好的,老哥再見~

公眾號

相關推薦

Offer收割機JVM生存還是毀滅

這兩天,廣州的天氣又開始熱了起來,又到了小動物交配的季節,啊呸,又到了一個收割 offer 的季節。年底將至,又到了面試的高峰期,JVM 作為Java 程式設計師面試繞不過的一道坎兒,它又來了,你準備好了嗎? 說說引用 面試官 A:小夥幾,上篇我們說到了 JVM 收集的兩種演算法 —— 引用記數法和可達性

每日五分鐘,玩轉JVM執行緒獨佔區

前言 如果我們對計算機組成有所瞭解,那麼我們一定會知道在計算機中有一塊兒特殊的區域,稱之為暫存器,暫存器包括了指令暫存器和程式計數器,這兩樣位於CPU中,作為程式執行的大腦來控制程式的執行和流轉。 而在JVM中,作為一種虛擬機器,JVM沒有指令暫存器,它是基於棧 + 程式計數器的體系結構來完成方法的執行,之所

每日五分鐘,玩轉JVM執行緒共享區

前言 上一篇中,我們瞭解了JVM中的執行緒獨佔區,這節課我們就來了解一下JVM中的執行緒共享區,JVM中的執行緒共享區是跟隨JVM啟動時一起建立的,包括堆(Heap)和方法區()兩部分,而執行緒獨佔區的程式計數器,虛擬機器棧,本地方法棧的生命週期都是跟隨執行緒的,隨執行緒的建立而誕生,隨執行緒的銷燬而銷燬。

每日五分鐘,玩轉JVM物件從哪來

面向物件 眾所周知,Java是一門面向物件的高階程式語言,那麼現在問題來了,物件從哪來呢?有些人會說通過new關鍵字來建立一個物件,說的很好,本篇我們就來解密在new一個物件的過程中,JVM都給我們做了什麼工作。 走哪來,到哪去 一個物件的誕生必定有一個類,通常我們都是通過new關鍵字例項化一個類來獲取該類的

每日五分鐘,玩轉JVM物件記憶體佈局

概覽 一個物件根據不同情況可以被劃分成兩種情況,當物件是一個非陣列物件的時候,物件頭,例項資料,對齊填充在記憶體中三分天下,而陣列物件中在物件頭中多了一個用於描述陣列物件長度的部分 物件頭 物件頭分為兩部分,第一部分稱之為"Mark Word",第二部分是用於獲取該物件型別的型別指標,

每日五分鐘,玩轉 JVMGC 概覽

前言 GC(Garbage Collection)是我們在學習 JVM 的過程中不可避免的一道坎,接下來,我們就來系統的學習一下 GC。 做一件事情之前,我們一定要去知道我們為什麼要去做,這裡不僅僅指 GC,更適用我們日常的學習和生活,知其然,知其所以然,方能百戰不殆。 下面我們先去了解為什麼要有 GC,

每日五分鐘,玩轉JVM指標壓縮

64位JVM和32位JVM 最初的時候,JVM是32位的,但是隨著64位系統的興起,JVM也迎來了從32位到64位的轉換,32位的JVM對比64位的記憶體容量比較有限,但是我們使用64位虛擬機器的同時,也帶來了一個問題,64位下的JVM中的物件會比32位中的物件多佔用1.5倍的記憶體空間,這是我們不想看到的

每天五分鐘,玩轉 JVM物件訪問定位

### 前言 在「物件記憶體佈局」一節中,我們瞭解到物件頭中包含了一個叫做**型別指標**的東西,即物件指向它的類元資料的指標,虛擬機器通過這個指標來確定這個物件是哪個類的例項。但是,並不是所有的虛擬機器都是這麼去做的。不同的虛擬機器關於這點有不同的實現,目前主流的方式可以分為**控制代碼**和**直接指標

給產品經理講JVM垃圾收集演算法

糾結的我,給我的JVM系列終於起了第三個名字,害,我真是太難了。從 JVM 到 每日五分鐘,玩轉 JVM 再到現在的給產品經理講 JVM ,雖然內容為王,但是標題可以讓更多的人看到我的文章,所以,歷經了三個選題,最終定下來了這個。 這個名字的由來,且聽我給你慢慢道來,從學習知識的角度上來說,最深入的方法就是把

合作伙伴大賽第一篇 | 誰是 DHR 時代的體驗提升

2018 SAP SuccessFactors on SAP Cloud Platform 合作伙伴開發創意大賽—競選預熱第一篇! 在「體驗為王」的網際網路時代,一款產品或服務所能提供的良好使用者體驗,不僅是贏得使用者芳心的砝碼,亦會成為影響企業口碑甚至其市場興衰的關鍵。 「201

運維技術週刊 ( 第 1 期 )

本文首發於:微信公眾號「運維之美」,公眾號 ID:Hi-Linux。 ​「運維之美」是一個有情懷、有態度,專注於 Linux 運維相關技術文章分享的公眾號。公眾號致力於為廣大運維工作者分享各類技術文章和釋出最前沿的科技資訊。公眾號的核心理念是:分享,我們認為只有分享才能使我們的團體更強大。如果你想第一時

山禾說成長手把手教你搭建一個完全屬於自己的技術部落格

搭建前的準備 在我們正式開始搭建一個完全屬於我們自己的部落格之前,我們首先要做好一些事前的準備(當然,如果你沒有做好準備也沒有關係,下面會一步一步的教你搞定這些) 伺服器一臺 or github 賬號一個(二選一)域名一個(可選)node.js(建議10.0以上版本)git 域名和伺服器的購買我這裡就不在文

未明學院學員報告最強微信小程式打造

報告作者:鄒格格、馮雨晴、劉儼黎      未明學院商業資料分析訓練營9月班學員 報告名稱:《最強微信小程式打造之路-微信小程式專案分析報告》 自2017年1月9日小程式正式上線後,微信以不斷的開放平臺能力,極有耐心地在為小程式逐步加溫。在

面試必備高頻演算法題終章圖文解析 + 範例程式碼 矩陣 二進位制 + 位運算 + LRU 合集

Attention 秋招接近尾聲,我總結了 牛客、WanAndroid 上,有關筆試面經的帖子中出現的演算法題,結合往年考題寫了這一系列文章,所有文章均與 LeetCode 進行核對、測試。歡迎食用 本文將覆蓋 「二進位制」 + 「位運算」 和 Lru 方面的面試演算法題,文中我將給出: 面試中的題目

GitHub 系列怎樣使用 GitHub?

pub nod 生成 就會 ref 不用 lose pos 這也 1.寫在前邊的話,為什麽要寫CitHub? 跟朋友在交流的時候聽到求職的時候發現有些公司要附Github帳號,一個優秀的 GitHub 賬號當然能讓你增色不少。自己之前聽說過,但沒有花時間研究,最後花了時間

GitHub 系列團隊合作利器 Branch

部分 描述 star 團隊 block 上線 流程 導致 建議 Git 相比於 SVN 最強大的一個地方就在於「分支」,Git 的分支操作簡直不要太方便,而實際項目開發中團隊合作最依賴的莫過於分支了,關於分支前面的系列也提到過,但是本篇會詳細講述什麽是分支、分支的具體操作

深入Java虛擬機(2)Class類文件結構

1.5 trac 三種 type 類構造 face 方法 class throw Java是與平臺無關的語言,這得益於Java源代碼編譯後生成的存儲字節碼的文件,即Class文件,以及Java虛擬機的實現。不僅使用Java編譯器可以把Java代碼編譯成存儲字節碼的Class

深入Java虛擬機(4)類加載機制

來講 合並 field 數字 對象 例如 二進制 種類 jar 類加載過程 類從被加載到虛擬機內存中開始,到卸載出內存為止,它的整個生命周期包括:加載、驗證、準備、解析、初始化、使用和卸載七個階段。 其中類加載的過程包括了加載、驗證、準備、解析、初始化五個階段。在這五個階段

深入Java虛擬機(6)Java語法糖

拆裝箱 重載 jdk1 支持 名稱 不存在 語法糖 pub 簽名 語法糖(Syntactic Sugar),也稱糖衣語法,是由英國計算機學家Peter.J.Landin發明的一個術語,指在計算機語言中添加的某種語法,這種語法對語言的功能並沒有影響,但是更方便程序員使用。Ja

七牛雲 X 美拍四年相伴,攜手突圍,打造泛知識內容生態

tlv 每天 一站式 個性 激發 監管 精準 雲服務 高清 9 月 15 日,深耕短視頻領域四年的美拍在廈門舉辦了四周年生日慶典,400 余名美拍達人齊聚,打造了中國首個「泛知識短視頻市集」。眾多在美拍成長起來的 KOL,在第一時間為美拍慶生。??美拍是一款備受年輕群體喜愛