【專題】Java技術(shù)體系

這是《深入理解Java虛擬機(jī)》的讀書筆記。

java生態(tài)

1、Java技術(shù)體系

  • Java程序設(shè)計(jì)語言
  • 各硬件平臺上的Java虛擬機(jī)
  • Class文件格式
  • Java API類庫
  • 來自商業(yè)機(jī)構(gòu)或者開源社區(qū)的第三方Java類庫
Java技術(shù)體系

2、Java運(yùn)行時數(shù)據(jù)區(qū)

  • 程序計(jì)數(shù)器:是一塊較小的內(nèi)存空間,是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。唯一一個沒有OOM的內(nèi)存區(qū)域。
  • Java虛擬機(jī)棧:生命周期與線程相同。描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法執(zhí)行時都會創(chuàng)建一個棧幀,用于存儲局部變量表、操作棧、動態(tài)鏈接、方法出口等信息。一個方法被調(diào)用執(zhí)行的過程就是棧幀在虛擬機(jī)棧中從入棧到出棧的過程。

成員變量
* 成員變量定義在類中,在整個類中都可以被訪問。
* 成員變量隨著對象的建立而建立,隨著對象的消失而消失,存在于對象所在的堆內(nèi)存中。
* 成員變量有默認(rèn)初始化值。
局部變量
* 局部變量只定義在局部范圍內(nèi),如:函數(shù)內(nèi),語句內(nèi)等,只在所屬的區(qū)域有效。
* 局部變量存在于棧內(nèi)存中,作用的范圍結(jié)束,變量空間會自動釋放。
* 局部變量沒有默認(rèn)初始化值

  • 本地方法棧:和java虛擬機(jī)棧作用類似,只不過java虛擬機(jī)棧為虛擬機(jī)執(zhí)行java方法服務(wù),而本地方法棧為虛擬機(jī)使用到的Native方法服務(wù)。有些虛擬機(jī)把java虛擬機(jī)棧和本地方法棧合二為一了。

  • Java堆:幾乎所有的對象實(shí)例都在這里分配內(nèi)存。是垃圾收集器管理的主要區(qū)域,因此也叫“GC堆”,還好沒叫垃圾堆。雖然是線程共享,也可能劃分多個線程私有的分配緩沖區(qū)(TLAB)。從垃圾收集器算法角度可以把堆分成:新生代和老年代;在細(xì)點(diǎn)可以有Eden空間、From Survivor空間、To Survivor空間等。當(dāng)前虛擬機(jī)堆都是可擴(kuò)展的,可通過-Xmx最大值和-Xms最小值控制,設(shè)置成一樣可避免堆自動擴(kuò)展。

  • 方法區(qū):用于存儲已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時編譯的代碼等數(shù)據(jù)。

Java運(yùn)行時數(shù)據(jù)區(qū)

程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧三個區(qū)域隨線程生而生,雖線程滅而滅。其中棧幀隨著方法的進(jìn)入和退出而有條不紊的執(zhí)行著入棧和出棧操作。每個棧幀分配多少內(nèi)存在類結(jié)構(gòu)確定下來時就已知了,這幾個區(qū)域內(nèi)存分配和回收都具有穩(wěn)定性,不需要過多考慮回收問題,線程滅就自動回收了。java堆和方法區(qū)的內(nèi)存都是動態(tài)分配和回收的。方法區(qū)進(jìn)行垃圾收集“性價比”比較低,主要還是管理Java堆。

對象訪問

主流的訪問方式有兩種:句柄和直接指針。在各種語言和框架中這兩種訪問方式都很常見,各有千秋。

句柄訪問
java堆中劃出一塊內(nèi)存作為句柄池,句柄中包含對象實(shí)例數(shù)據(jù)和類型數(shù)據(jù)各自的具體地址信息。最大的好處就是reference中存儲的是穩(wěn)定的句柄地址,在對象被移動的時候只改變句柄的實(shí)例數(shù)據(jù)指針。(垃圾收集時移動對象是非常常見的現(xiàn)象)

句柄訪問

直接指針
Java堆中的對象布局必須考慮如何防止類型數(shù)據(jù)地址。reference中存儲的直接就是對象地址。最大的好處就是速度快,節(jié)省一次指針定位的時間開銷。

直接指針

再談引用

引用:當(dāng)reference類型的數(shù)據(jù)中存儲的數(shù)值代表的是另一塊內(nèi)存的起始地址,就稱其為引用。引用有如下4中類型:

  • 強(qiáng)引用:只要強(qiáng)引用還存在,GC永遠(yuǎn)不會回收被引用的對象;

  • 軟引用(SoftReference):描述一些還有用,但不是必須的對象。對于只有軟引用的對象,內(nèi)存不足時,在OOM之前會被回收。

  • 弱引用(WeakReference):描述的也是非必須的對象,但程度比軟引用弱。只能存活到下次垃圾收集器工作之前,也就是說只要垃圾收集器工作,這種引用的對象都會被回收,不管當(dāng)前內(nèi)存是否足夠。

  • 虛引用(PhantomReference):又稱幽靈引用或者幻影引用。它是最弱的一種引用關(guān)系。虛引用不會影響對象的生存時間,通過虛引用也無法獲取對象實(shí)例。設(shè)置虛引用的唯一目的就是在對象對收集器回收時收到一個系統(tǒng)的通知。

3、垃圾收集器

確定對象是否已死

  • 引用計(jì)數(shù)器:給對象添加一個引用計(jì)數(shù)器,每當(dāng)有地方引用對象時,計(jì)數(shù)器就加1,當(dāng)引用失效時,計(jì)數(shù)器就減1。當(dāng)計(jì)數(shù)器等于0時,對象就不再可能被使用了。
    優(yōu)點(diǎn):實(shí)現(xiàn)簡單,判定效率高。
    缺點(diǎn):很難解決對象間循環(huán)引用的問題。

  • 根搜索算法:通過一系列名為“GC Roots”的對象作為起點(diǎn)向下搜索,搜索所走過的路徑成為引用鏈。當(dāng)一個對象到GC Roots沒有任何引用鏈時,則證明這個對象不再可能被使用了。

在Java中可作為GC Roots的對象有
* 虛擬機(jī)棧中引用的對象(棧幀中本地變量表)
* 方法區(qū)中的類靜態(tài)屬性引用的對象
* 方法區(qū)中的常量引用的對象
* 本地方法棧幀中JNI引用的對象

收集器判斷對象不可達(dá)后,會檢查對象的finalize()方法是否被執(zhí)行過,如果沒有就先執(zhí)行finalize()。一個對象的finalize()只會被執(zhí)行一次,如果一個對象在finalize()方法中被救活了,即重新被引用了,當(dāng)它再次不可達(dá)時不會執(zhí)行finalize()方法了。

垃圾收集算法

  • 標(biāo)記-清除算法(Mark-Sweep):顧名思義收集分為“標(biāo)記”和“清除”兩個階段。標(biāo)記就是上面介紹的標(biāo)記對象死亡的過程。

優(yōu)點(diǎn):這是最基礎(chǔ)的收集算法,其他的算法都是它的基礎(chǔ)上演變來的。
缺點(diǎn):1、效率問題,標(biāo)記和清除效率都不高;2、空間問題,標(biāo)記清除后產(chǎn)生大量的不連續(xù)的內(nèi)存碎片。

  • 復(fù)制算法(Copying):將內(nèi)存分成大小相等的A、B兩塊,每次只使用其中一塊,比如A,當(dāng)A使用完了,就把還存活的對象拷到B上,然后把A空間一次清掉。

優(yōu)點(diǎn):實(shí)現(xiàn)簡單、運(yùn)行效率高。
缺點(diǎn):可使用的內(nèi)存縮小為原來的一半
改進(jìn):IBM研究表面,新生代中98%的對象都是朝生夕死,所以并不需要1:1來劃分。所以分成一塊較大的Eden空間和a、b兩塊較小的Survivor空間(Eden:Survivor = 8:1)。每次使用Eden和一塊Survivor空間,比如Survivor-a,用完了就把存活的對象拷到Survivor-b上,然后清除Eden和Survivor-a,然后再使用Eden和Survivor-b。每次浪費(fèi)10%的空間,如果存活對象大于10%就把多出來的對象放到給新生代擔(dān)保的老年代。

目前商業(yè)虛擬機(jī)都采用改進(jìn)后的復(fù)制算法回收新生代。

  • 標(biāo)記-整理算法(Mark-Compact):標(biāo)記還是對象標(biāo)記的那個標(biāo)記。整理是把存活的對象移動到內(nèi)存的一端,然后清理掉端邊界以外的內(nèi)存。

  • 分代收集算法(Generational Collection):這個算法沒有新思想。只是根據(jù)對象存活周期將內(nèi)存劃分成新生代和老年代兩塊。然后不同的年代采用不同收集算法,新生代用復(fù)制算法,老年代因?yàn)闆]有額外空間給它內(nèi)存擔(dān)保,而且對象存活時間長,那就用標(biāo)記-整理或者標(biāo)記-清除。

4、類加載

Class文件需要被加載到虛擬機(jī)中才能被運(yùn)行和使用。生命周期包括:加載(Loading)、驗(yàn)證(Verification)、準(zhǔn)備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)七個階段。

類加載器

虛擬機(jī)中類的唯一性由類本身和它的加載器決定。

雙親委派模型的父子關(guān)系不是繼承,而是組合關(guān)系。


雙親委派模型

雙親委派模型的工作工程:類加載器收到類加載請求時,首先不會嘗試自己加載這個類,而是把這個請求委派給父類加載器去完成,每一層加載器都是如此,所以所有的加載請求都會傳遞到啟動類加載器,只有父加載器反饋?zhàn)约簾o法完成這個加載請求時(它的搜索范圍中沒有找到所需的類),子加載器才會嘗試自己去加載。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評論 2 380

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

  • 《深入理解Java虛擬機(jī)》筆記_第一遍 先取看完這本書(JVM)后必須掌握的部分。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,143評論 1 34
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,339評論 11 349
  • 內(nèi)存溢出和內(nèi)存泄漏的區(qū)別 內(nèi)存溢出:out of memory,是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,...
    Aimerwhy閱讀 754評論 0 1
  • 823fdd1d51c4閱讀 97評論 0 1
  • 板山位于寧洱縣東部的勐先鄉(xiāng),該鄉(xiāng)屬中切中山河谷地貌特征,為瀾滄江水系,勐先大河由北向南流經(jīng)勐先全境。該鄉(xiāng)轄11個村...
    5ebc5e57260e閱讀 884評論 0 0