Jvm相關(guān)知識點

Jvm組成部分

1. PC寄存器/程序計數(shù)器

一塊小的內(nèi)存空間炫欺,作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器伶跷。分支蚓炬,循環(huán)松逊,跳轉(zhuǎn),異常處理肯夏,線程恢復(fù)等基礎(chǔ)功能都依賴計數(shù)器完成经宏。在任何一個時刻,一個處理器只會執(zhí)行一條線程中的指令驯击,因此烁兰,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程需要一個獨立的程序計數(shù)器(私有內(nèi)存)徊都。Java方法的計數(shù)器記錄正在執(zhí)行的虛擬機字節(jié)碼指令的地址沪斟,Native方法的計數(shù)器為空。計數(shù)器不存在OutofMemoryError.

2. Jvm棧

Jvm棧也是線程私有的暇矫,生命周期與線程相同主之。Jvm棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法被執(zhí)行的時候都會創(chuàng)建一個棧幀(stackframe)用于存儲局部變量表,操作棧李根,動態(tài)鏈接槽奕,方法出口等信息。每一個方法被調(diào)用直至執(zhí)行完成的過程房轿,就對應(yīng)著一個棧幀在Jvm棧從入棧到出棧的過程史翘。局部變量表存放了基本數(shù)據(jù)類型(boolean,byte冀续,char琼讽,short,int洪唐,float钻蹬,long,double)凭需,對象引用(指向?qū)ο蟮刂返闹羔槪┖蛂eturnAddress(指向一條字節(jié)碼指令的地址)问欠。在方法運行期間不會改變局部變量表大小。

3. 本地方法棧

本地方法棧作用與Jvm棧作用類似粒蜈,區(qū)別不過是Jvm棧執(zhí)行的是Java方法顺献,本地方法棧執(zhí)行的是Native方法。

4. Jvm堆

Jvm堆是Jvm內(nèi)存最大的一塊枯怖,被所有線程所共享注整。Jvm堆在Jvm啟動時創(chuàng)建,此內(nèi)存區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例都在這里分配內(nèi)存肿轨。Jvm堆是垃圾收集器(GC)管理的主要區(qū)域寿冕。Jvm堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的即可椒袍。因為堆是Jvm中所有線程所共享的驼唱,因此在其上進行對象內(nèi)存分配均需要進行加鎖,這也導(dǎo)致了new對象的開銷是比較大的驹暑。Sun Hotspot Jvm為了提升對象內(nèi)存分配的效率玫恳,對于所創(chuàng)建的線程都會分配一塊獨立的空間TLAB(Thread Local Allocation Buffer),其大小由Jvm根據(jù)運行的情況計算而得优俘,在TLAB上分配對象不用加鎖京办,因此Jvm給線程分配對象的內(nèi)存時會盡可能的在TLAB上分配,如果對象過大兼吓,則仍需在堆空間分配臂港。TLAB僅作用于Eden Space森枪。

5. 方法區(qū)

與Jvm堆一樣视搏,方法區(qū)是各個線程共享的區(qū)域,它用于存儲已被虛擬機加載的類信息县袱,常量浑娜,靜態(tài)變量,即時編譯器編譯后的代碼等數(shù)據(jù)式散。方法區(qū)也可以叫永生代筋遭,但是Hotspot準(zhǔn)備放棄永生代,使用Native Memory來實現(xiàn)方法區(qū)暴拄。相對而言漓滔,GC在這個區(qū)域比較少的出現(xiàn),這個區(qū)域內(nèi)回收目標(biāo)主要是常量池和對類型的卸載乖篷。

6. 運行時常量池

運行時常量池是方法區(qū)的一部分,這里存放的是類中的固定的常量信息,方法和Field的引用信息捌臊。

Jvm垃圾回收機制

觸發(fā)GC的條件:

1)GC在優(yōu)先級最低的線程中進行或链,一般在應(yīng)用程序空閑,即沒有應(yīng)用程序在運行時鲸沮,被調(diào)用琳骡。

2)例外: 當(dāng)Jvm堆內(nèi)存不足時,GC會被調(diào)用讼溺。當(dāng)應(yīng)用線程正在運行楣号,并且在運行過程中創(chuàng)建對象,若這時內(nèi)存不足,Jvm會強制調(diào)用GC竖席。若一次GC之后仍不能滿足內(nèi)存分配耘纱,Jvm會再次進行兩次GC,若仍不能滿足毕荐,Jvm報OutofMemoryError,Java應(yīng)用停止束析。

GC的Generation算法(分代收集算法)

分代收集算法是大部分Jvm的垃圾收集器采用的算法。他的核心思想是根據(jù)對象存活的生命周期憎亚,將內(nèi)存劃分為若干個不同的區(qū)域员寇。一般情況下將堆分為老年代新生代,方法區(qū)為永生代(新版本將永生代廢棄第美,引入元空間的概念蝶锋,永生代使用Jvm內(nèi)存兒元空間直接使用物理內(nèi)存)。新生代分為Eden區(qū)和Survivor區(qū)(Survivor from和Survivor to)什往,大小比例默認為8:1:1.新產(chǎn)生的對象優(yōu)先進入Eden區(qū)扳缕,當(dāng)Eden區(qū)滿了之后再使用Survivor from,當(dāng)Survivor from也滿了之后别威,就進行Minor GC(新生代GC)躯舔,將Eden和Survivor from中存活的對象使用Copying算法復(fù)制進入Survivor to,原來的Survivor to就成了新的Survivor from省古,Copying算法在復(fù)制之后清空Eden和Survivor from粥庄,原來的Survivor from就成了新的Survivor to。復(fù)制的時候豺妓,如果Survivor to無法容納全部存活的對象惜互,則根據(jù)老年代的分配擔(dān)保,將對象復(fù)制進入老年代琳拭,如果老年代也無法容納训堆,則進行Full GC(老年代GC或者稱為Major GC)。老年代的特點就是每次垃圾收集時白嘁,只有少量對象需要被回收坑鱼,而新生代的特點是每次都要回收大量的對象,因此可以根據(jù)不同代的特點采取合理的收集算法权薯。程序中主動調(diào)用System.gc()強制執(zhí)行的GC為Full GC姑躲。
Jvm對新生代采用Copying算法,因為新生代每次GC都要回收大部分對象盟蚣,需要復(fù)制的操作次數(shù)較少黍析;
老年代的特點是每次GC只回收少量對象,一般使用Mark-Compact算法屎开;

1)大對象直接進入老年代阐枣,Jvm有個參數(shù)配置,大于這個值直接進入老年代,避免Eden和Survivor區(qū)之間發(fā)生大量的對象復(fù)制操作蔼两。

2)長期存活的對象進入老年代甩鳄,Jvm給每個對象定義一個對象年齡計數(shù)器,如果對象在Eden出生额划,經(jīng)歷一次Minor GC之后仍存活妙啃,將其移入Survivor區(qū)并且年齡+1.每經(jīng)過一次GC年齡+1,當(dāng)年齡到達15(Jvm參數(shù),默認為15)俊戳,移入老年代揖赴。

3)但是Jvm不是永遠要求年齡必須達到最大年齡才可以晉升老年代,如果Survivor空間中相同年齡(如年齡X)的所有對象大小的總和大于Survivor的一半時抑胎,年齡大于等于X的所有對象直接進入老年代燥滑。

簡單的三個收集算法

1)標(biāo)記清除算法:

分標(biāo)記,清除兩個階段阿逃。首先標(biāo)記所需要回收的對象铭拧,在標(biāo)記完成之后統(tǒng)一回收所有被標(biāo)記的對象。不足:一個效率問題恃锉,標(biāo)記和清除的效率都不高搀菩;一個空間問題,標(biāo)記清除之后產(chǎn)生了大量不連續(xù)的內(nèi)存碎片,碎片太多導(dǎo)致需要分配大對象時無法找到足夠的連續(xù)內(nèi)存而不得不再觸發(fā)一次GC淡喜。

2)復(fù)制算法Copying:

為了解決效率問題秕磷,復(fù)制算法將可用的內(nèi)存分為兩部分诵闭,每次只使用其中一塊炼团,當(dāng)一塊內(nèi)存用完了,將還存活的對象復(fù)制到另一塊上面疏尿,然后再把剛剛用過的內(nèi)存空間一次性清理掉瘟芝,這樣解決了碎片問題。

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

復(fù)制算法在對象存活率較高時就會頻繁進行復(fù)制操作褥琐,效率將降低锌俱,因此有了Mark-Compact算法。標(biāo)記過程和標(biāo)記清除算法相同敌呈,但是后續(xù)不是直接清除對象贸宏,而是讓所有存活的對象向同一側(cè)移動,然后直接清理邊界以外的內(nèi)存磕洪。

兩種算法判定對象是否存活

1)引用計數(shù)算法:給對象中添加一個引用計數(shù)器吭练,每當(dāng)一個地方應(yīng)用了對象,計數(shù)器+1析显,當(dāng)引用失效鲫咽,計數(shù)器-1.計數(shù)器為0表示該對象已死,可回收。但是這個方法很難解決兩個對象循環(huán)相互引用的情況分尸。

2)可大型分析算法:通過一系列稱為“GC Roots”的對象作為起點锦聊,從這些節(jié)點開始向下搜索,搜索所走過的路徑稱為引用鏈箩绍,當(dāng)一個對象到GC Roots沒有任何引用鏈相連(即對象到GC Roots不可達)孔庭,則證明對象已死,可回收材蛛。Java中可以作為GC Roots的對象包括:Jvm棧中引用的對象史飞,本地方法棧中Native方法引用的對象,方法區(qū)靜態(tài)屬性引用的對象仰税,方法區(qū)常量引用的對象构资。主流實現(xiàn)中,都是通過可達性分析算法來判定對象是否存活陨簇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吐绵,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子河绽,更是在濱河造成了極大的恐慌己单,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耙饰,死亡現(xiàn)場離奇詭異纹笼,居然都是意外死亡,警方通過查閱死者的電腦和手機苟跪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門廷痘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人件已,你說我怎么就攤上這事笋额。” “怎么了篷扩?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵兄猩,是天一觀的道長。 經(jīng)常有香客問我鉴未,道長枢冤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任铜秆,我火速辦了婚禮淹真,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘羽峰。我一直安慰自己趟咆,他們只是感情好添瓷,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著值纱,像睡著了一般鳞贷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上虐唠,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天搀愧,我揣著相機與錄音,去河邊找鬼疆偿。 笑死咱筛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的杆故。 我是一名探鬼主播迅箩,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼处铛!你這毒婦竟也來了饲趋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤撤蟆,失蹤者是張志新(化名)和其女友劉穎奕塑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體家肯,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡龄砰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了讨衣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片换棚。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖值依,靈堂內(nèi)的尸體忽然破棺而出圃泡,到底是詐尸還是另有隱情碟案,我是刑警寧澤愿险,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站价说,受9級特大地震影響辆亏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鳖目,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一扮叨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧领迈,春花似錦彻磁、人聲如沸碍沐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽累提。三九已至,卻和暖如春磁浇,著一層夾襖步出監(jiān)牢的瞬間斋陪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工置吓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留无虚,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓衍锚,卻偏偏與公主長得像友题,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子戴质,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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

  • 1咆爽、java中的內(nèi)存模型 gc內(nèi)存模型:主要包括棧、堆置森、程序計數(shù)器斗埂,其中棧和程序計數(shù)器是線程私有的 1)棧:虛擬機...
    糖豆_7986閱讀 194評論 1 0
  • JVM架構(gòu) 當(dāng)一個程序啟動之前,它的class會被類裝載器裝入方法區(qū)(Permanent區(qū))凫海,執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,664評論 0 7
  • Java8張圖 11呛凶、字符串不變性 12、equals()方法行贪、hashCode()方法的區(qū)別 13漾稀、...
    Miley_MOJIE閱讀 3,704評論 0 11
  • 原文閱讀 前言 這段時間懈怠了,罪過建瘫! 最近看到有同事也開始用上了微信公眾號寫博客了崭捍,挺好的~給他們點贊,這博客我...
    碼農(nóng)戲碼閱讀 5,968評論 2 31
  • 內(nèi)存溢出和內(nèi)存泄漏的區(qū)別 內(nèi)存溢出:out of memory啰脚,是指程序在申請內(nèi)存時殷蛇,沒有足夠的內(nèi)存空間供其使用,...
    Aimerwhy閱讀 741評論 0 1