JVM常見面試題

簡單介紹下JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)

 Jvm在執(zhí)行Java程序的過程中會把它管理的內(nèi)存分為若干個(gè)不同的區(qū)域尔邓,這些部分有些是線程私有的刮吧,有些則是線程共享的。
線程私有的:程序計(jì)數(shù)器泽本,虛擬機(jī)棧,本地方法棧
線程共享的:方法區(qū)漾月,堆

簡單介紹下JVM常見異常

StackOverFlowError:當(dāng)線程請求棧的深度超過當(dāng)前 Java虛擬機(jī)棧的最大深度時(shí)
OutOfMemoryError:
  1)當(dāng)線程請求棧時(shí)內(nèi)存用完了熊泵,無法再動態(tài)擴(kuò)展了
  2)當(dāng)堆內(nèi)存或者永久代/元空間不夠,無法再分配對象或存放數(shù)據(jù)箕般,同時(shí)堆空間或用就代空間無法再拓展
  3)當(dāng)垃圾回收器占用JVM的資源98%耐薯,同時(shí)回收效率不到2%

程序計(jì)數(shù)器

  記錄當(dāng)前線程正在執(zhí)行的字節(jié)碼的地址或行號,主要作用是為了保證多線程情況下JVM程序的正常運(yùn)行

講一講方法區(qū)

  方法區(qū)所有線程共享隘世,主要用于存儲類的信息可柿、常量池、方法數(shù)據(jù)丙者、方法代碼等
  方法區(qū)邏輯上屬于堆的一部分复斥,但是為了與堆進(jìn)行區(qū)分,通常又叫“非堆”械媒。

JVM中對象的創(chuàng)建過程

虛擬機(jī)遇到一跳new指定時(shí)目锭,根據(jù)new的參數(shù)是否能在常量池中定位到一個(gè)類的符號引用
如果沒有,那就必須先執(zhí)行相應(yīng)的類加載過程
在類加載的檢查通過后纷捞,接下來虛擬機(jī)將為新生對象分配內(nèi)存痢虹,對象所需內(nèi)存大小在類加載完成后就可以完全確定,
為對象分配空間的任務(wù)等同于將一塊確定大小的內(nèi)存從Java堆中劃分出來,
真的就這么簡單嗎主儡?顯然不是奖唯,具體的實(shí)現(xiàn)是比較復(fù)雜,下面將描述完整的過程
1糜值、檢查加載
  先執(zhí)行相應(yīng)的類加載過程丰捷,如果沒有,則進(jìn)行類加載
2寂汇、內(nèi)存分配
  1)假如Java堆中內(nèi)醋是絕對規(guī)整的病往,所有用過的內(nèi)存都放在一邊,空閑的內(nèi)存放在另一邊骄瓣,中間放著一個(gè)指針作為分界點(diǎn)的指示器
  那所分配內(nèi)存就僅僅把那個(gè)指針向空閑那邊挪動一段與對象大小相等的距離
  這種分配方式被稱為“指針碰撞”
  2)如果Java堆中內(nèi)存不是規(guī)整的停巷,已使用的內(nèi)存和空間的內(nèi)存相互交錯,那么就沒有辦法簡單地進(jìn)行指針碰撞了
  虛擬機(jī)必須維護(hù)一個(gè)列表,記錄哪些內(nèi)存是可用的畔勤,在分配的時(shí)候從列表找到一塊足夠大的空間劃分給對象實(shí)例蕾各,并更新列表上的記錄
  這種分配方式稱為“空閑列表”
  
  選擇哪種分配方式由Java堆是否規(guī)整決定,而Java堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定
  比如使用CMS這種基于Mark-Sweep算法的收集器時(shí)硼被,Java堆中的內(nèi)存并不是規(guī)整的示损,通常采用空閑列表
3、內(nèi)存空間初始化
  內(nèi)存分配完成后嚷硫,虛擬機(jī)需要將分配到的內(nèi)存空間都初始化為默認(rèn)值(如int默認(rèn)值為0检访,boolean為false等)
  這一步操作保證了對象的實(shí)例字段在Java代碼中可以不賦初始值就能直接使用,程序能訪問到這些字段的數(shù)據(jù)類型所對應(yīng)的初始值
4仔掸、設(shè)置
  接下來脆贵、虛擬機(jī)要對對象進(jìn)行必要的設(shè)置
  假如這個(gè)對象是哪個(gè)類的實(shí)例,如何才能找到類的元數(shù)據(jù)信息起暮、對象的哈希碼卖氨、對象的GC分代年齡等信息,這些信息存放在對象的對象頭之中负懦。
5筒捺、對象初始化 
  以上4步完成后,從虛擬機(jī)的視角看纸厉,一個(gè)新的對象已經(jīng)產(chǎn)生了系吭,但從Java程序的視角來看,對象的創(chuàng)建才剛剛開始颗品,所有的字段都還為初始值肯尺,所以一般來說,執(zhí)行new指令后會接著把對象按照開發(fā)者的意愿進(jìn)行初始化躯枢,這個(gè)一個(gè)真正可用的對象才算完全產(chǎn)生出來则吟。

對象的訪問定位的兩種方式

  句柄和直接指針兩種方式
  句柄:Java堆中會劃分出一塊內(nèi)存來作為句柄池,reference中存儲的就是對象的句柄地址锄蹂,而句柄中包含了對象實(shí)例數(shù)據(jù)與數(shù)據(jù)類型各自的具體地址信息
  直接指針:Java堆對象的布局中就必須考慮到如何放置訪問類型數(shù)據(jù)的相關(guān)信息氓仲,而reference中存儲的就是對象的地址。
  
HotSpot中使用直接指針得糜,使用直接指針訪問的方式最大的好處就是速度快敬扛,它節(jié)省了一次指針定位的時(shí)間開銷

JVM如何判斷對象是否可回收

  可達(dá)性分析算法
  這個(gè)算法的基本思想就是通過一系列的成為“GC Roots”的對象作為起點(diǎn),從這些借點(diǎn)開始向下搜索掀亩,節(jié)點(diǎn)所走過的路徑稱為引用鏈
  當(dāng)一個(gè)對象到GC Roots沒有仁和應(yīng)用鏈相連,則證明這個(gè)對象不可用的欢顷。

簡單的介紹一下Java中的各種引用

1槽棍、強(qiáng)引用:
  通常我們使用的大部分引用實(shí)際上都是強(qiáng)引用,這是使用普通的引用,如果一個(gè)對象具有強(qiáng)引用炼七,垃圾回收期絕不會回收它
  當(dāng)內(nèi)存空間不足時(shí)缆巧,Java虛擬機(jī)則會拋出OutOfMemoryError錯誤,使程序異常終止豌拙。
2陕悬、軟引用:
  如果一個(gè)對象只具有軟引用,當(dāng)內(nèi)存空間足夠時(shí)按傅,垃圾回收器就不會回收它捉超,但如果內(nèi)存空間不足時(shí),就會回收這些對象的內(nèi)存
  只要垃圾回收器沒有回收它唯绍,該對象就可以被程序使用拼岳,軟引用可以用來實(shí)現(xiàn)內(nèi)存敏感的高速緩存。 
  軟引用可以和一個(gè)引用隊(duì)列(referenceQueue)聯(lián)合使用况芒;
  如果軟引用所引用的對象被垃圾回收惜纸,Java虛擬機(jī)就會把這個(gè)軟引用加入與之關(guān)聯(lián)的引用隊(duì)列中。
3绝骚、弱引用
  弱引用與軟引用的區(qū)別在于只具有軟引用的對象擁有更短暫的生命周期耐版。
  在垃圾回收器線程掃描它管轄的內(nèi)存區(qū)域時(shí),不管內(nèi)存是否足夠压汪,都會將掃描到只具有弱引用的對象的內(nèi)存回收
  不過由于垃圾回收是一個(gè)優(yōu)先級很低的線程粪牲,因此不一定會很快發(fā)現(xiàn)那些只有被弱引用的對象。
4蛾魄、虛引用
  虛引用并不會決定對象的生命周期虑瀑,如果一個(gè)對象僅持有虛引用,在任何時(shí)候都有可能被垃圾回收滴须。
  虛引用主要用來跟蹤對象被垃圾回收的活動舌狗。

程序設(shè)計(jì)中除了強(qiáng)引用,使用軟引用的情況較多扔水,這是因?yàn)檐浺每梢约铀貸VM對垃圾內(nèi)存的回收速度痛侍,可以維護(hù)系統(tǒng)的運(yùn)行安全,防止內(nèi)存溢出等問題產(chǎn)生魔市。

垃圾收集有哪些算法主届,各自的特點(diǎn)?

1待德、標(biāo)記-清除算法
  標(biāo)記-清除算法分為“標(biāo)記”和“清除”階段君丁,首先標(biāo)記出所有需要回收的對象,在標(biāo)記完后統(tǒng)一回收所有被標(biāo)記的對象将宪。
  它是最基礎(chǔ)的收集算法啊绘闷,  效率也很高橡庞,但是會帶來明顯的問題:
  1)效率問題
  2)空間問題(標(biāo)記清除后會產(chǎn)生大量不連續(xù)的碎片)
2、復(fù)制算法
  為了解決效率問題印蔗,復(fù)制收集算法出現(xiàn)了扒最。
  它可以將內(nèi)存分為大小相同的兩塊,每次使用其中的一塊华嘹,當(dāng)這一塊內(nèi)存使用完后吧趣,就將還存貨的對象復(fù)制到另一塊去,然后再把使用的空間一次清理掉耙厚。
  這樣就使每次的內(nèi)存回收都是對內(nèi)存區(qū)間的一半進(jìn)行回收强挫。
3、標(biāo)記-整理算法
  根據(jù)老年代的特點(diǎn)出的一種標(biāo)記算法颜曾,標(biāo)記過程仍然與“標(biāo)記-清除”算法一致
  但后續(xù)步驟不是直接對可回收對象回收纠拔,而是讓所有存活的對象向一端移動,然后直接清理掉端邊界以外的內(nèi)存泛豪。

HotSpot為什么要分為新生代和老年代

將Java堆分為新生代和老年代稠诲,我們就可以根據(jù)各個(gè)年代的特點(diǎn),選擇合適的垃圾收集算法诡曙。
在新生代中臀叙,每次收集都會有大量對象死去,所以我們可以選擇復(fù)制算法价卤,只需要付出少量對象的復(fù)制成本就可以完成每次垃圾收集劝萤。
在老年代中,對象的存活幾率比較好慎璧,而且沒有額外的空間對它進(jìn)行分配擔(dān)保床嫌,所以我們必須選擇“標(biāo)記-清除”或“標(biāo)記-整理”算法進(jìn)行垃圾收集。

哪些情況需要對類進(jìn)行初始化胸私?

虛擬機(jī)規(guī)范嚴(yán)格規(guī)定了有些只有5種情況必須立即對類進(jìn)行初始化:
1厌处、使用new關(guān)鍵字實(shí)例化對象的時(shí)候、讀取或設(shè)置一個(gè)類的靜態(tài)字段時(shí)岁疼,已經(jīng)調(diào)用一個(gè)類的靜態(tài)方法時(shí)阔涉。
2、使用java.lang.reflect包的方法對類進(jìn)行反射調(diào)用時(shí)捷绒,如果類沒有初始化瑰排,則需要先觸發(fā)其初始化。
3暖侨、當(dāng)初始化一個(gè)類的時(shí)候椭住,如果發(fā)現(xiàn)其父類沒有被初始化,就會先初始化它的父親字逗。
4京郑、當(dāng)虛擬機(jī)啟動時(shí)显押,用戶需要指定一個(gè)要執(zhí)行的主類,虛擬機(jī)會先初始化這個(gè)類傻挂。
5、使用動態(tài)語言支持的時(shí)候  
  如果一個(gè)java.lang.invoke.MethodHanddle實(shí)例最后的解析結(jié)果REF_getStatic.REF_putstatic,REF_invokeStatic的方法句柄
  并且這個(gè)方法句柄所對應(yīng)的類沒有進(jìn)行初始化挖息,而需要先觸發(fā)其初始化金拒。

雙親委派模型

雙親委派模型,要求除了頂層的啟動類加載器外套腹,其他的類加載器都應(yīng)該有自己的父類加載器绪抛。
這里的父子關(guān)系通常是子類通過組合關(guān)系而不是繼承關(guān)系來服用父類加載器的代碼。
雙親委派模型的工作過程:如果一個(gè)類加載器收到了類加載的請求
先把這個(gè)請求委派給父類加載器完成电禀,只有父類加載器反饋?zhàn)约簾o法完成加載請求時(shí)
子類加載器才回嘗試自己去加載幢码。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市尖飞,隨后出現(xiàn)的幾起案子症副,更是在濱河造成了極大的恐慌,老刑警劉巖政基,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贞铣,死亡現(xiàn)場離奇詭異,居然都是意外死亡沮明,警方通過查閱死者的電腦和手機(jī)辕坝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荐健,“玉大人酱畅,你說我怎么就攤上這事〗。” “怎么了纺酸?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長扛稽。 經(jīng)常有香客問我吁峻,道長,這世上最難降的妖魔是什么在张? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任用含,我火速辦了婚禮,結(jié)果婚禮上帮匾,老公的妹妹穿的比我還像新娘啄骇。我一直安慰自己,他們只是感情好瘟斜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布缸夹。 她就那樣靜靜地躺著痪寻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪虽惭。 梳的紋絲不亂的頭發(fā)上橡类,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音芽唇,去河邊找鬼顾画。 笑死,一個(gè)胖子當(dāng)著我的面吹牛匆笤,可吹牛的內(nèi)容都是我干的研侣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼炮捧,長吁一口氣:“原來是場噩夢啊……” “哼庶诡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咆课,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤末誓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后书蚪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體基显,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年善炫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撩幽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡箩艺,死狀恐怖窜醉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情艺谆,我是刑警寧澤榨惰,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站静汤,受9級特大地震影響琅催,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜虫给,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一藤抡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抹估,春花似錦缠黍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽替饿。三九已至,卻和暖如春贸典,著一層夾襖步出監(jiān)牢的瞬間视卢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工廊驼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腾夯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓蔬充,卻偏偏與公主長得像,于是被迫代替她去往敵國和親班利。 傳聞我的和親對象是個(gè)殘疾皇子饥漫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355