JVM內(nèi)存模型

1灵份、類的加載、連接和初始化

? ? ? 加載:查找并加載類的二進(jìn)制數(shù)據(jù)(字節(jié)碼文件)

? ? ? 連接:

? ? ? ? ? ? ?驗(yàn)證:確保被加載的類的正確性(手工生成class文件割捅,可

? ? ? ? ? ? ? ? ? ? ? ? 能不符合JVM標(biāo)準(zhǔn)規(guī)范)

? ? ? ? ? ? ?準(zhǔn)備:為類的靜態(tài)變量分配內(nèi)存何什,并將其初始化為默認(rèn)值

? ? ? ? ? ? ? ? ? ? ?(這個時候并不涉及new對象的操作)

? ? ? ? ? ? ?解析:把類中的符號引用轉(zhuǎn)換為直接引用(Child.run()轉(zhuǎn)

? ? ? ? ? ? ? ? ? ? ? ? 換為pointer)

? ? ? 初始化:為類的靜態(tài)變量賦予正確的初始值(正確:用戶賦予的

? ? ? ? ? ? ? ? ? ? 值)

? ? ? 示例:MyTest

? ?1.1類的使用方式:

? ? ? ? 所有的類或接口只有在java程序“首次主動使用”才會初始化

? ? ? ? 主動使用:

? ? ? ? ? ? ? ?(1)創(chuàng)建類的實(shí)例new Test();

? ? ? ? ? ? ? ?(2)訪問某個類的靜態(tài)變量,或者為某個類的靜態(tài)變量賦值:a =

? ? ? ? ? ? ? ? ? ? Test.b; Test.b = a;

? ? ? ? ? ? ? ?(3)調(diào)用類的靜態(tài)方法:Test.doSomething();

? ? ? ? ? ? ? ?(4)初始化一個類的子類:

? ? ? ? ? ? ? ? ? ? class Parent{};class Childextends Parent{

? ? ? ? ? ? ? ? ? ? public static int a= 3};

? ? ? ? ? ? ? ? ? ? Child.a =4;

? ? ? ? ? ? ? (5) java虛擬機(jī)就啟動時被標(biāo)明為啟動類的類(java TestTest

? ? ? ? ? ? ? ? ? ?中有main方法)

? ? ? ? ? ? ? (6)反射Class.forName(“Test”);

? ? ? ? ?除此之外的使用都是被動使用漫贞,被動使用是不會觸發(fā)初始化的。

? ?1.2類的加載:

? ? ? ? 將.class文件中的二進(jìn)制數(shù)據(jù)讀入到內(nèi)存中育叁,將其放在運(yùn)行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi)绕辖,然后在堆區(qū)創(chuàng)建一個java.lang.Class對象,又 來封裝在方法區(qū)內(nèi)的數(shù)據(jù)結(jié)構(gòu)擂红,class對象是jvm在類加載時自動創(chuàng)建的仪际。

? 1.3類加載器

? ? ? ? Java虛擬機(jī)自帶的類加載器:

? ? ? ?根類加載器(Bootstrap)(c++ java代碼中無法獲取該類)

? ? ? ?擴(kuò)展類加載器(Extension)(java )

? ? ? ?系統(tǒng)類加載器(System)(也叫應(yīng)用加載器)

? ? ? ?用戶自定義的類加載器

? ?層次關(guān)系:


? ? ? ?根類加載器:用c++實(shí)現(xiàn)围小,并沒有集成java.lang.ClassLoader類

? ? ? ?擴(kuò)展類記載器:父類加載器為根類加載器,加載目錄jre\lib\ext树碱,如果把用戶創(chuàng)建的jar包放在這個目錄下肯适,則會有擴(kuò)展類加載器? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 進(jìn)行加載。

? ? ? ?系統(tǒng)類加載器:父類加載器為擴(kuò)展類加載器成榜,從環(huán)境變量classpath或系統(tǒng)屬性java.class.path所指定的目錄加載類框舔,是自定義? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?加載類的默認(rèn)父類加載器。

? ? ? (1)核心類庫由bootstrap加載器進(jìn)行加載赎婚,獲取到為空刘绣,其他都可獲取,例Test2

? ? ? (2)調(diào)用一個類的靜態(tài)變量挣输,且這個靜態(tài)變量在編譯時期就可以確定纬凤,則不會進(jìn)行類的初始化,當(dāng)這個類在執(zhí)行階段才能確? ? ? ? ? ? ? ? ? ? ?定撩嚼,則會進(jìn)行初始化停士,例Test4,Test3

? ? ? (3)加載順序—啟動類—父類—子類完丽,例Test5恋技,Test6

? ? ? (4)調(diào)用loadClass方法加載一個類,并不是對類的主動使用逻族,并不會初始化該類蜻底。例Test7

? 1.4類的加載機(jī)制—父委托機(jī)制

? ? ? (1)除了java自帶的根類加載器,其余類加載器都有且僅有一個父類加載器聘鳞,只有當(dāng)父類加載器不能進(jìn)行加載的時候薄辅,才會由? ? ? ? ? ? ? ? 子類加載器進(jìn)行加載。

? ? ? (2)父子加載器并非繼承關(guān)系搁痛,子加載器并不一定繼承父類加載器

? ? ? (3)安全考慮长搀,每個類都會有確定的層次中的一個類加載器進(jìn)行加載宇弛,自定義除外鸡典。

? ? ?(4)每個類都有自己的命名空間,命名空間由該類加載器及所有父類加載器所加載的類組成枪芒。同一個命名空間中彻况,不會存在兩? ? ? ? ? ? ? ? 個完整名字相同的類,不同命名空間中舅踪,可能存在完整名字相同的類纽甘。

? 1.5 用戶自定義類加載器

? ? ? ? 繼承ClassLoader類,覆蓋findClass方法抽碌,會由loadClass方法調(diào)用悍赢。

? ?1.6 JVM虛擬機(jī)執(zhí)行整體順序


2、JVM的內(nèi)存結(jié)構(gòu)


方法區(qū)和對是所有線程共享的內(nèi)存區(qū)域;而java棧左权、本地方法棧和程序員計(jì)數(shù)器是運(yùn)行是線程私有的內(nèi)存區(qū)域皮胡。

程序計(jì)數(shù)器:當(dāng)前線程所執(zhí)行字節(jié)碼指令的行號指示器,線程私有赏迟,執(zhí)行java方法屡贺,計(jì)數(shù)器記錄的是java代碼的行號,執(zhí)行native方法則為null(undefined)锌杀;

虛擬機(jī)棧:線程私有甩栈,表示java方法執(zhí)行的內(nèi)存模型,每個棧幀對應(yīng)的是一個調(diào)用的方法糕再,包括局部變量表量没、動態(tài)鏈接、操作數(shù)棧亿鲜、指向當(dāng)前方法所屬的類的運(yùn)行時常量池允蜈、方法返回地址和附加信息。


棧幀是保存在虛擬機(jī)棧中的蒿柳,棧幀是用來存儲數(shù)據(jù)和存儲部分過程結(jié)果的數(shù)據(jù)結(jié)構(gòu)饶套,同時也被用來處理動態(tài)鏈接(Dynamic Linking)、方法返回值和異常分派(Dispatch Exception)垒探。線程運(yùn)行過程中妓蛮,只有一個棧幀是處于活躍狀態(tài),稱為“當(dāng)前活躍棧幀”圾叼,當(dāng)前活動棧幀始終是虛擬機(jī)棧的棧頂元素蛤克。


局部變量表:方法參數(shù),方法內(nèi)部定義的變量夷蚊。

操作數(shù)棧:每一個方法的調(diào)用构挤,都會建立一個操作數(shù)棧

動態(tài)鏈接:與靜態(tài)解析對應(yīng),一部分的符號引用會在運(yùn)行是轉(zhuǎn)化為直接引用

方法返回地址:正常完成出口惕鼓,異常完成出口

本地方法棧:線程私有筋现,與虛擬機(jī)棧類似,為native方法服務(wù)

堆:線程共享箱歧,存儲對象本身及數(shù)組

方法區(qū):線程共享矾飞,類信息,靜態(tài)變量呀邢,常量洒沦,編譯后的代碼等

運(yùn)行時常量池:存放編譯期生成的各種字面量和符號引用

2.1對象的創(chuàng)建—內(nèi)存分配

(1)jvm遇到一個new指令,檢查這個指令的參數(shù)是否能在常量池中定位到一個類的符號引用价淌,然后檢查這個類代表的類是否已被加載申眼、解析和初始化瞒津。如果沒有,則進(jìn)行類加載括尸。

(2)類的加載—先加載父類仲智,先加載靜態(tài)塊,順序加載姻氨。

(3)JVM開始為對象分配內(nèi)存钓辆,兩種方式:

指針碰撞:java堆內(nèi)存規(guī)整,GC帶有壓縮整理功能

空閑列表:java堆內(nèi)存空間并不規(guī)整肴焊。

解決多線程分配內(nèi)存的問題:

失敗重試:保證更新操作的原子性

本地線程緩存惹傲:TLAB,在啟動線程時娶眷,就會在堆中給該線程預(yù)留一個內(nèi)存空間

(4)內(nèi)存分配完后似嗤,首先內(nèi)存空間都初始化為零值。若使用TLAB届宠,則在分配TLAB時即已初始化成功烁落。

(5)設(shè)置對象頭(Object Header):如何才能找到類的元數(shù)據(jù)信息,對象的哈希碼豌注,對象的GC分代年齡等信息伤塌。

(6)執(zhí)行方法,將對象初始化為指定的值轧铁。

3每聪、GC垃圾回收

3.1判斷對象失效

(1)引用計(jì)數(shù)算法

給對象添加一個引用計(jì)數(shù)器,每當(dāng)有一個地方引用它齿风,計(jì)數(shù)器值就加1药薯,當(dāng)引用失效就減1,計(jì)數(shù)器為0的對象就是不可能再被引用的對象救斑。

實(shí)現(xiàn)簡單童本,但無法解決循環(huán)引用的問題

(2)可達(dá)性分析算法

通過一系列成為“GC ROOT”的對象作為起始點(diǎn),向下搜索脸候,走過的路徑成為引用鏈穷娱,當(dāng)一個對象到GC ROOT沒有任何引用鏈相連時,則證明此對象是不可用的纪他。

可作為GC ROOT的對象有:

虛擬機(jī)棧中引用的對象

方法區(qū)中靜態(tài)屬性引用的對象

方法區(qū)中常量引用的對象

本地方法棧中JNI(native方法)引用的對象


3.2垃圾回收算法

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

先對不用的對象進(jìn)行標(biāo)記鄙煤,然后清除


(2)復(fù)制算法

將內(nèi)存按容量分為幾塊晾匠,在一個時間段只使用一塊內(nèi)存茶袒,當(dāng)這塊內(nèi)存用完,則將內(nèi)存清理干凈凉馆,然后將可用的對象復(fù)制到另一個區(qū)域薪寓。



(3)標(biāo)記—整理算法

復(fù)制算法在對象存活率較高時要進(jìn)行較多的復(fù)制操作亡资,效率將變低,而且浪費(fèi)空間向叉。

標(biāo)記—整理的標(biāo)記過程與標(biāo)記—清除一樣锥腻,但后續(xù)步驟不是對可回收對象進(jìn)行清理,而是讓所有存活的對象都向一端移動母谎,然后直接清理掉端邊界以外的內(nèi)存瘦黑。


(4)分代收集算法

根據(jù)對象存活周期的不同將內(nèi)存劃分為幾塊,一般把java堆分為新生代和老年代奇唤。

在新生代中每次垃圾收集時都發(fā)現(xiàn)有大批對象死去幸斥,只有少量存活,就選用復(fù)制算法咬扇,只需要付出少量存活對象的復(fù)制成本就可以完成收集甲葬。而老年代因?yàn)閷ο蟠婊盥矢悖瑳]有額外空間對它進(jìn)行分配擔(dān)保懈贺,就必須使用標(biāo)記—清理或標(biāo)記—整理算法來進(jìn)行回收

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末经窖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子梭灿,更是在濱河造成了極大的恐慌画侣,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堡妒,死亡現(xiàn)場離奇詭異棉钧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)涕蚤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門宪卿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人万栅,你說我怎么就攤上這事佑钾。” “怎么了烦粒?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵休溶,是天一觀的道長。 經(jīng)常有香客問我扰她,道長兽掰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任徒役,我火速辦了婚禮孽尽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忧勿。我一直安慰自己杉女,他們只是感情好瞻讽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著熏挎,像睡著了一般速勇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坎拐,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天烦磁,我揣著相機(jī)與錄音,去河邊找鬼哼勇。 笑死个初,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猴蹂。 我是一名探鬼主播院溺,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼磅轻!你這毒婦竟也來了珍逸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤聋溜,失蹤者是張志新(化名)和其女友劉穎谆膳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撮躁,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漱病,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了把曼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杨帽。...
    茶點(diǎn)故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嗤军,靈堂內(nèi)的尸體忽然破棺而出注盈,到底是詐尸還是另有隱情,我是刑警寧澤叙赚,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布老客,位于F島的核電站,受9級特大地震影響震叮,放射性物質(zhì)發(fā)生泄漏胧砰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一苇瓣、第九天 我趴在偏房一處隱蔽的房頂上張望尉间。 院中可真熱鬧,春花似錦、人聲如沸乌妒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撤蚊。三九已至,卻和暖如春损话,著一層夾襖步出監(jiān)牢的瞬間侦啸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工丧枪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留光涂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓拧烦,卻偏偏與公主長得像忘闻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恋博,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評論 2 355

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