麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

jvm基礎(chǔ)

2019-11-06 07:18:57
字體:
供稿:網(wǎng)友

1、什么是JVM ?

JVM, 中文名是java虛擬機(jī), 正如它的名字, 是一個(gè)虛擬機(jī)器,來模擬通用的物理機(jī)。 JVM是一個(gè)標(biāo)準(zhǔn),一套規(guī)范,  規(guī)定了.class文件在其內(nèi)部運(yùn)行的相關(guān)標(biāo)準(zhǔn)和規(guī)范。 及其相關(guān)的內(nèi)部構(gòu)成。 比如:所有的JVM都是基于棧結(jié)構(gòu)的運(yùn)行方式。那么不符合這種要求的,不算是JVM, 如Android中所使用的Dalvik 虛擬機(jī)就不能稱作是JAVA 虛擬機(jī), 因?yàn)樗腔诩拇嫫鳎ㄗ钚碌腁ndroid系統(tǒng)據(jù)說已經(jīng)放棄了Dalvik VM, 而是使用ART)。

JVM相關(guān)的產(chǎn)品有很多, 通常最有名的莫過于現(xiàn)在Oracle公司所有的HotSpot 虛擬機(jī)。因此, 這里討論的都是HotSpot虛擬機(jī), 如果沒有特別說明。 

2、類加載?

類加載, 是通過JVM的類加載器從JVM外部以二進(jìn)制字節(jié)流的方式加載到JVM中。但JVM本身有至少三種類加載器:BootStrap(根類加載器,C++實(shí)現(xiàn), 加載位于jre/lib/rt.jar)、Extension(擴(kuò)展類加載器, 主要用于加載jre/lib/ext/下的jar)、System(加載classpath環(huán)境變量所指定的class);當(dāng)然還有,自定義的類加載器(用于實(shí)現(xiàn)自己的類加載器, 如Tomcat中就實(shí)現(xiàn)多個(gè)類加載器,用來管理不同的jar)。如果, 我有一個(gè)HelloWorld的類需要加載, 首先類加載器會(huì)去從最底層的類加載器去驗(yàn)證這個(gè)類是否被加載, 如果沒有, 則委托給上一次的類加載器驗(yàn)證是否被加載, 如果到BootStrap類加載器都沒有發(fā)現(xiàn)HelloWorld類被加載, 那么類加載器將執(zhí)行加載任務(wù), 如果根類加載器沒有加載, 則委托給下一級(jí)的Extension類加載器去嘗試加載,直到這個(gè)類被加載成功。 參考下圖:需要注意的是:如果一個(gè)類被不同的類加載器加載, 那么就是兩個(gè)不同的類。

3、類加載的具體過程?

被java編譯器(不僅限于, 還有其他任何的可以編輯成為.class的編譯器)編譯過的.class文件(可能是以jar、war、jsp等形式), 經(jīng)過類加載器加載 、 驗(yàn)證、準(zhǔn)備、解析、初始化之后, 才可以被使用。基本的過程如下:

加載: 首先,通過一個(gè)類的全類名來獲取此類的二進(jìn)制字節(jié)流。其次,將類中所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)換為運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu), 最后,生成一個(gè)代表加載的類的java.lang.Class對(duì)象, 作為方法區(qū)這個(gè)類的所有數(shù)據(jù)的訪問入口。加載完成之后, 虛擬機(jī)外部的二進(jìn)制靜態(tài)數(shù)據(jù)結(jié)構(gòu)就轉(zhuǎn)換成了虛擬機(jī)所需要的結(jié)構(gòu)存儲(chǔ)在方法區(qū)中(至于如何轉(zhuǎn)換, 則由具體虛擬機(jī)自己定義實(shí)現(xiàn)), 而所生成的Class對(duì)象, 則存放在方法區(qū)中, 用來作為程序訪問方法區(qū)中數(shù)據(jù)的外部接口。驗(yàn)證:其目的就是保證加載進(jìn)來的.class文件不會(huì)危害到虛擬機(jī)本身, 且內(nèi)容符合當(dāng)前虛擬機(jī)規(guī)范要求。主要驗(yàn)證的內(nèi)容大致有:文件格式、元數(shù)據(jù)驗(yàn)證、字節(jié)碼驗(yàn)證、符號(hào)引用驗(yàn)證。其中文件格式驗(yàn)證, 主要確保符合class文件格式規(guī)范(如文本后綴為.class的文件將驗(yàn)證不通過), 以及主次版本號(hào), 驗(yàn)證是否當(dāng)前JVM可以處理等。元數(shù)據(jù)驗(yàn)證,主要驗(yàn)證編譯后的字節(jié)碼描述信息是否符合java語法規(guī)范。字節(jié)碼驗(yàn)證, 其最為復(fù)雜, 主要通過控制流和數(shù)據(jù)流確定語義是否合法、符合邏輯。符號(hào)引用驗(yàn)證,可以看做是除自身以外(常量池中各種引用符號(hào))的信息匹配校驗(yàn),如通過持有的引用能否找到對(duì)應(yīng)的實(shí)例。準(zhǔn)備:正式為類變量分配內(nèi)存,并設(shè)置類變量的初始值。這些變量都會(huì)在方法區(qū)中進(jìn)行分配。解析:將常量池內(nèi)的符號(hào)引用替換為直接引用的過程。主要針對(duì)類或接口、字段、類方法、接口方法、方法類型、方法句柄等。初始化:加載的最后階段, 程序真正運(yùn)行的開始。

4、java運(yùn)行時(shí)數(shù)據(jù)區(qū) ?

既然類以及加載到JVM中, 那么數(shù)據(jù)如何真正的運(yùn)行?如下圖:類加載進(jìn)來, JVM是通過上圖所示的區(qū)域來運(yùn)行和管理這些加載進(jìn)來的CLASS。即程序運(yùn)行的是時(shí)候, 由上面邏輯單元來運(yùn)行程序, 包括:方法區(qū)、堆、本地方法棧、棧、程序計(jì)數(shù)器(PC)五大部分組成(有些VM說常量池也是其中的一個(gè)單元, 但是HotSpot VM中的常量池是方法區(qū)中的一部分)。(注意線程共享)程序計(jì)數(shù)器 (PC):可以看做是當(dāng)前線程執(zhí)行字節(jié)碼的行號(hào)指示器。字節(jié)碼解釋器工作的時(shí)候就是通過這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令, 分支, 循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能依賴計(jì)數(shù)器完成。虛擬機(jī)棧:和計(jì)數(shù)器一樣, 也是線程私有的,生命周期同線程一致。每個(gè)方法在執(zhí)行時(shí),都會(huì)創(chuàng)建一個(gè)棧幀,用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。方法調(diào)入則入棧, 方法執(zhí)行完則出站。局部變量表存儲(chǔ)各種基本類型數(shù)據(jù)(java的8種,其中l(wèi)ong,double占用2個(gè)局部變量控件,其余數(shù)據(jù)占用1個(gè))、對(duì)象引用(reference類型)。局部變量表所需的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個(gè)方法時(shí), 這個(gè)方法需要在幀中分配多大的局部變量空間是完全確定的。在方法運(yùn)行期間是不會(huì)改變局部變量表的大小的。本地方法棧:此棧和JVM棧作用非常類似, 不同在于本地方法棧為虛擬機(jī)使用到的Native方法服務(wù), 而JVM棧則是為Java執(zhí)行的方法服務(wù)。Sun HotSpot虛擬機(jī), 直接把本地方法棧和虛擬機(jī)棧合二為一。本地方法棧也會(huì)拋出StackOverFlowError和OutOfMemoryError異常。Java堆:是JVM管理內(nèi)存中最大的一塊。被所有線程共享一塊區(qū)域。堆是GC垃圾收集器管理的主要區(qū)域。從內(nèi)存回收角度看, java堆被分為新生代、老年代, 再細(xì)致一點(diǎn)有其他的劃分。這些目的主要就是更快的分配和回收內(nèi)存。

方法區(qū):和java堆相同, 線程共享區(qū)域, 用來存儲(chǔ)已被虛擬機(jī)加載的類信息, 常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。有人稱作此方法區(qū)為“永久帶”, 本質(zhì)上不等價(jià),只是HotSpot VM將GC分代收集擴(kuò)展到了方法區(qū),這樣HotSpot的垃圾收集器管理方法區(qū)和管理java堆一樣(優(yōu)點(diǎn):不用專門為方法區(qū)寫一套垃圾收集器, 缺點(diǎn):容易導(dǎo)致內(nèi)存溢出)。官方現(xiàn)在擁也有放棄永久帶并改為采用Native Memory來實(shí)現(xiàn)方法區(qū)的計(jì)劃,目前已經(jīng)發(fā)布的JDK7中的HotSpot中, 已經(jīng)將原本放在方法區(qū)中的字符串常量池移出了。

運(yùn)行時(shí)常量池:是方法區(qū)的一部分。Class文件中除了有類的版本、字段、方法、接口等描述外,還有一項(xiàng)就是常量池, 用于存放編譯期間生成的各種字面量和符號(hào)引用 ,這部分內(nèi)容在類加載后進(jìn)入方法區(qū)的運(yùn)行時(shí)常量池中存放。

5、垃圾收集?

在java運(yùn)行時(shí)區(qū)域中, 程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧3個(gè)區(qū)域隨線程而生,隨程而滅。因?yàn)檫@幾個(gè)區(qū)域的內(nèi)存分配和回收都是具有確定性,這幾個(gè)區(qū)域不需要過多考慮回收的問題。因?yàn)榉椒ńY(jié)束之后或線程結(jié)束之后, 內(nèi)存自然就跟著回收了(這不是絕對(duì)的, 因?yàn)槿绻?dāng)棧內(nèi)存中的引用很消耗內(nèi)存的時(shí)候, 需要手動(dòng)將引用置為null,以便垃圾收集器回收大對(duì)象)。而java堆和方法區(qū)不一樣,一個(gè)接口中的多個(gè)實(shí)現(xiàn)類需要的內(nèi)存可能不一樣, 一個(gè)方法中的多個(gè)分支需要的內(nèi)存也可能不一樣,我們只有在程序處于運(yùn)行期間時(shí),才知道會(huì)創(chuàng)建哪些對(duì)象, 垃圾收集器關(guān)注的就是這部分內(nèi)存。其也是動(dòng)態(tài)的。垃圾收集器的區(qū)域如下圖:垃圾收集本是有一套非常復(fù)雜的算法, 如果在方法區(qū)中(HotSpot VM中的永久帶)進(jìn)行垃圾收集, 那么其性價(jià)比極底的,因?yàn)槔厥罩饕占谰脦е械膬刹糠謨?nèi)容:廢棄的常量和無用的類。回收永久帶中的常量和方法區(qū)非常相似。但是在堆中, 尤其是在新生代中,常規(guī)應(yīng)用進(jìn)行一次垃圾收集, 一般可以回收70%——95%的空間。而永久帶的垃圾收集要遠(yuǎn)地與此。如上圖所示, 每一個(gè)黑框中都是一個(gè)垃圾收集器, 對(duì)應(yīng)特定的垃圾收集算法, 來挺高整體的垃圾收集效率。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 久久污| 护士hd老师fre0性xxx | 日韩视频中文 | 日韩黄色影视 | 久久99精品久久久久久小说 | 一级黄色欧美 | 午夜视频国产 | 色播亚洲 | 成人免费毛片在线观看 | 亚洲成人在线视频网 | 亚洲国产美女视频 | 日本精品一区二区 | 成人精品一区二区三区中文字幕 | 亚洲综合网站 | 久久综合九色综合久久久精品综合 | 日本在线不卡一区二区 | 49vvv| 91美女视频在线 | 欧美3p激情一区二区三区猛视频 | 爱视频福利 | www.91在线观看 | 国产精品午夜在线观看 | 天天看天天摸天天操 | 羞羞电影在线观看 | 成人观看网站 | 欧美一级免费看 | 美女毛片儿 | 国产精品啪一品二区三区粉嫩 | 精品亚洲夜色av98在线观看 | 毛片免费观看视频 | 91精品国产乱码久久久久久久久 | 精品国产一区二区三区久久久蜜月 | 久久久久夜色精品国产老牛91 | 久久精品视频在线免费观看 | 欧美18一19sex性护士农村 | 色女人在线 | 久精品久久 | 成人区精品一区二区婷婷 | 性感美女一级毛片 | 久久亚洲激情 | 日本在线观看视频网站 |