JVM知識

對象分配原則

  • 對象優(yōu)先分配在Eden區(qū),如果Eden區(qū)沒有足夠的空間時度帮,虛擬機執(zhí)行一次Minor GC腺办。
  • 大對象直接進入老年代(大對象是指需要大量連續(xù)內(nèi)存空間的對象)藻雌。這樣做的目的是避免在Eden區(qū)和兩個Survivor區(qū)之間發(fā)生大量的內(nèi)存拷貝(新生代采用復(fù)制算法收集內(nèi)存)
  • 長期存活的對象進入老年代。虛擬機為每個對象定義了一個年齡計數(shù)器吨掌,如果對象經(jīng)過了1次Minor GC那么對象會進入Survivor區(qū)半抱,之后每經(jīng)過一次Minor GC那么對象的年齡加1,知道達到閥值對象進入老年區(qū)
  • 動態(tài)判斷對象的年齡膜宋。如果Survivor區(qū)中相同年齡的所有對象大小的總和大于Survivor空間的一半窿侈,年齡大于或等于該年齡的對象可以直接進入老年代
  • 空間分配擔(dān)保。每次進行Minor GC時秋茫,JVM會計算Survivor區(qū)移至老年區(qū)的對象的平均大小史简,如果這個值大于老年區(qū)的剩余值大小則進行一次Full GC,如果小于檢查HandlePromotionFailure設(shè)置肛著,如果true則只進行Monitor GC,如果false則進行Full GC

類加載器

  • 啟動類加載器:Bootstrap ClassLoader圆兵,負責(zé)加載存放在JDK\jre\lib(JDK代表JDK的安裝目錄跺讯,下同)下,或被-Xbootclasspath參數(shù)指定的路徑中的殉农,并且能被虛擬機識別的類庫
  • 擴展類加載器:Extension ClassLoader刀脏,該加載器由sun.misc.Launcher$ExtClassLoader實現(xiàn),它負責(zé)加載DK\jre\lib\ext目錄中超凳,或者由java.ext.dirs系統(tǒng)變量指定的路徑中的所有類庫(如javax.*開頭的類)愈污,開發(fā)者可以直接使用擴展類加載器
  • 應(yīng)用程序類加載器:Application ClassLoader,該類加載器由sun.misc.Launcher$AppClassLoader來實現(xiàn)聪建,它負責(zé)加載用戶類路徑(ClassPath)所指定的類钙畔,開發(fā)者可以直接使用該類加載器

Java對象結(jié)構(gòu)

Java對象由三個部分組成:對象頭、實例數(shù)據(jù)金麸、對齊填充擎析。
對象頭由兩部分組成,第一部分存儲對象自身的運行時數(shù)據(jù):哈希碼挥下、GC分代年齡揍魂、鎖標識狀態(tài)、線程持有的鎖棚瘟、偏向線程ID(一般占32/64 bit)现斋。第二部分是指針類型,指向?qū)ο蟮念愒獢?shù)據(jù)類型(即對象代表哪個類)偎蘸。如果是數(shù)組對象庄蹋,則對象頭中還有一部分用來記錄數(shù)組長度。
實例數(shù)據(jù)用來存儲對象真正的有效信息(包括父類繼承下來的和自己定義的)
對齊填充:JVM要求對象起始地址必須是8字節(jié)的整數(shù)倍(8字節(jié)對齊)

如何判斷對象可以被回收迷雪?

判斷對象是否存活一般有兩種方式:

  • 引用計數(shù):每個對象有一個引用計數(shù)屬性限书,新增一個引用時計數(shù)加1,引用釋放時計數(shù)減1章咧,計數(shù)為0時可以回收倦西。此方法簡單,無法解決對象相互循環(huán)引用的問題赁严。
  • 可達性分析(Reachability Analysis):從GC Roots開始向下搜索扰柠,搜索所走過的路徑稱為引用鏈。當(dāng)一個對象到GC Roots沒有任何引用鏈相連時疼约,則證明此對象是不可用的卤档,不可達對象。

JVM的永久代中會發(fā)生垃圾回收么程剥?

垃圾回收不會發(fā)生在永久代裆装,如果永久代滿了或者是超過了臨界值,會觸發(fā)完全垃圾回收(Full GC)。如果你仔細查看垃圾收集器的輸出信息哨免,就會發(fā)現(xiàn)永久代也是被回收的茎活。這就是為什么正確的永久代大小對避免Full GC是非常重要的原因。請參考下Java8:從永久代到元數(shù)據(jù)區(qū) (注:Java8中已經(jīng)移除了永久代琢唾,新加了一個叫做元數(shù)據(jù)區(qū)的native內(nèi)存區(qū))

引用分類

  • 強引用 : GC時不會被回收
  • 軟引用 : 描述有用但不是必須的對象载荔,在發(fā)生內(nèi)存溢出異常之前被回收
  • 弱引用 : 描述有用但不是必須的對象,在下一次GC時被回收
  • 虛引用(幽靈引用/幻影引用) : 無法通過虛引用獲得對象采桃,用PhantomReference實現(xiàn)虛引用懒熙,虛引用用來在GC時返回一個通知

OutOfMemoryError異常

  • (堆) Java對用于存儲對象實例,只要不斷的創(chuàng)建對象普办,并保證避免垃圾回收機制清除這些對象工扎,那么對象數(shù)量達到最大堆的容積之后就會內(nèi)存溢出
  • (虛擬機棧、本地方法棧) 虛擬機在擴展棧時無法申請到足夠的內(nèi)存空間
  • (運行時常量池) list.add(String.valueOf(i++).intern())衔蹲,提示信息是"PermGen space"
  • (方法區(qū)) 運行時產(chǎn)生大量的類去填滿方法區(qū)肢娘,直到溢出
  • (本機直接內(nèi)存) Unsafe.allocateMemory()

垃圾收集算法

算法 描述 優(yōu)點 缺點
標記-清除 首先標記出所有需要回收的對象,在標記 完成后統(tǒng)一回收掉所有被標記的對象 最基礎(chǔ)的收集算法 1.效率不高2.標記清除之后會 產(chǎn)生大量不連續(xù)的內(nèi)存碎片
復(fù)制 將可用的內(nèi)存容量劃分為兩個大小相等的兩塊舆驶, 每次只使用其中一塊橱健。當(dāng)這一塊的內(nèi)存使用完, 就將還存活的對象復(fù)制到另外一塊沙廉,然后將 已使用過的一次清理掉拘荡,適用于新生代 1.每次都是對半?yún)^(qū)進行內(nèi)存回收, 內(nèi)存分配時也不需要考慮內(nèi)存碎片等復(fù)雜情況 2.只需要移動堆頂指針撬陵,按順序分配內(nèi)存即可 3.實現(xiàn)簡單珊皿,運行高效 1.將內(nèi)存縮小為原來的一半,代價高 2.在對象存活率較高時就要進行較多 的復(fù)制操作巨税,效率將會變低
標記-整理 先標記出所有需要回收的對象蟋定,然后讓所有存 活的對象都想一端移動,然后直接清理掉端邊 界以外的內(nèi)存 適用于對象存活率高老年代
分代收集算法 把Java堆分成新生代和老年代垢夹,根據(jù)各個年代 的特點采用最適當(dāng)?shù)氖占惴āP律捎脧?fù)制维费, 老年代采用標記-清除或標記-整理

垃圾收集器

  • Serial收集器果元,最基本最古老的收集器,是一個單線程的收集器犀盟,可能產(chǎn)生較長時間的停頓而晒。Client模式下的虛擬機默認新生代的收集器
  • ParNew收集器,ParNew是Serial收集器的多線程版本阅畴。ParNew收集器在單CPU的環(huán)境中絕對不會有比Serial收集器更好的效果倡怎。它默認開啟的收集線程數(shù)與CPU數(shù)量相同,在CPU非常多的情況下,可以用-XX:ParallelGCThreads參數(shù)限制垃圾收集的線程
  • Parallel Scavenge收集器监署,是一個新生代收集器颤专、采用復(fù)制算法、并行的多線程收集器钠乏。Parallel Scavenge收集器的目的是達到一個可控制的吞吐量栖秕,吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)
  • Serial Old收集器,是Serial收集器的老年代版本晓避,同樣是一個單線程收集器簇捍,使用"標記-整理"算法
  • Parallel Old收集器,是Parallel Scavenge收集器的老年代版本俏拱,使用多線程和"標記-整理"算法
  • CMS(Concurrent Mark Sweep)收集器暑塑,是一種以獲取最短回收停頓時間為目標的收集器」兀基于"標記-清除"算法事格,整個過程分為4步:
    1. 初始標記 (CMS initial mark)
    2. 并發(fā)標記 (CMS concurrent mark)
    3. 重新標記 (CMS remark)
    4. 并發(fā)清除 (CMS concurrent sweep)
      其中,初始標記况毅、重新標記這兩個步驟仍然需要"Stop The World"分蓖。初始標記僅僅只是標記一下GC Roots能直接關(guān)聯(lián)到的對象,速度很快尔许;并發(fā)標記就是進行GC Roots Tracing定位么鹤,而重新標記是為了修正并發(fā)標記期間用戶程序繼續(xù)運作而導(dǎo)致標記產(chǎn)生變動的那一部分對象的標記記錄。
      整個過程中耗時最長的并發(fā)標記和并發(fā)清除都是跟用戶線程一起工作味廊,所以蒸甜,從總體上來說,CMS收集器內(nèi)存回收是與用戶線程一起并發(fā)執(zhí)行的
      缺點
    • CMS收集器對CPU資源非常敏感余佛。CMS默認啟動的回收線程數(shù)是(CPU數(shù)量+3)/4
    • CMS收集器無法處理浮動垃圾柠新,可能出現(xiàn)"Concurrent Mode Failure"失敗而導(dǎo)致另一次Full GC的產(chǎn)生
  • G1收集器,G1 (Garbage-First)是一款面向服務(wù)器的垃圾收集器,主要針對配備多顆處理器及大容量內(nèi)存的機器. 以極高概率滿足GC停頓時間要求的同時,還具備高吞吐量性能特征
    1. 初始標記 (Initial Marking)
    2. 并發(fā)標記
    3. 最終標記
    4. 篩選回收
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辉巡,一起剝皮案震驚了整個濱河市恨憎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌郊楣,老刑警劉巖憔恳,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異净蚤,居然都是意外死亡钥组,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門今瀑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來程梦,“玉大人点把,你說我怎么就攤上這事∮旄剑” “怎么了郎逃?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拿撩。 經(jīng)常有香客問我衣厘,道長,這世上最難降的妖魔是什么压恒? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任影暴,我火速辦了婚禮,結(jié)果婚禮上探赫,老公的妹妹穿的比我還像新娘型宙。我一直安慰自己,他們只是感情好伦吠,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布妆兑。 她就那樣靜靜地躺著,像睡著了一般毛仪。 火紅的嫁衣襯著肌膚如雪搁嗓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天箱靴,我揣著相機與錄音腺逛,去河邊找鬼。 笑死衡怀,一個胖子當(dāng)著我的面吹牛棍矛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抛杨,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼够委,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了茁帽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤潘拨,失蹤者是張志新(化名)和其女友劉穎恢共,沒想到半個月后战秋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體璧亚,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡讨韭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了透硝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡濒生,死狀恐怖埋泵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情罪治,我是刑警寧澤丽声,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布觉义,位于F島的核電站,受9級特大地震影響晒骇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜洪囤,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喇完。 院中可真熱鬧,春花似錦款咖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坏逢。三九已至赘被,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間民假,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工事秀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留彤断,地道東北人易迹。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像供炼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子袋哼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

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

  • 原文閱讀 前言 這段時間懈怠了闸衫,罪過! 最近看到有同事也開始用上了微信公眾號寫博客了楚堤,挺好的~給他們點贊,這博客我...
    碼農(nóng)戲碼閱讀 5,962評論 2 31
  • 這篇文章是我之前翻閱了不少的書籍以及從網(wǎng)絡(luò)上收集的一些資料的整理衅胀,因此不免有一些不準確的地方,同時不同JDK版本的...
    高廣超閱讀 15,599評論 3 83
  • 垃圾收集器在對堆進行回收前酥筝,需要先確定這些對象中哪些還“存活”著滚躯,哪些已經(jīng)“死去”(也就是不被任何引用類型所引用)...
    滿天星愛我閱讀 532評論 0 6
  • Java和C++之間有一堵由內(nèi)存動態(tài)分配和垃圾收集技術(shù)所圍成的“高墻”嘿歌,墻外面的人想進來,墻里面的人想出來宙帝。 對象...
    胡二囧閱讀 1,087評論 0 4
  • JVM架構(gòu) 當(dāng)一個程序啟動之前,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū))愿待,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,664評論 0 7