aaaa成人_日本一道本在线视频_国产高潮流白浆喷水在线观看_韩国专区福利一区二区_一区二区不卡视频_看全色黄大色黄大片女图片第一次

×

java虛擬機(jī)類(lèi)加載機(jī)制

  • 作者:新網(wǎng)
  • 來(lái)源:新網(wǎng)
  • 瀏覽:100
  • 2018-05-02 17:54:06

虛擬機(jī)把類(lèi)的數(shù)據(jù)從Class文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換解析、初始化,最后形成可以被虛擬機(jī)直接使用的Java類(lèi)型。這就是Java虛擬機(jī)的類(lèi)加載機(jī)制。

   虛擬機(jī)把類(lèi)的數(shù)據(jù)從Class文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換解析、初始化,最后形成可以被虛擬機(jī)直接使用的Java類(lèi)型。這就是Java虛擬機(jī)的類(lèi)加載機(jī)制。

<div>  與編譯時(shí)需要連接的語(yǔ)言不同,Java語(yǔ)言類(lèi)加載、連接和初始化都是在程序執(zhí)行期間完成的,增加了性能開(kāi)銷(xiāo)但提高了就Java程序的靈活性,Java里天生可以動(dòng)態(tài)擴(kuò)展的語(yǔ)言特性就依賴運(yùn)行期動(dòng)態(tài)加載和動(dòng)態(tài)鏈接這個(gè)特點(diǎn)完成的。
t018d18e21ebcabe958.jpg
 
  2.類(lèi)加載的時(shí)機(jī)
  (1)類(lèi)從加載到虛擬機(jī)內(nèi)存,到卸載出內(nèi)存,整個(gè)生命周期:加載、驗(yàn)證、準(zhǔn)備、解析、初始化、使用、卸載。其中驗(yàn)證、準(zhǔn)備、解析統(tǒng)稱連接。
  (2)加載、驗(yàn)證、準(zhǔn)備、初始化、卸載這5個(gè)階段順序是確定的(開(kāi)始時(shí)間順序一定,進(jìn)行或完成通常是交叉的),解析可能在初始化后再開(kāi)始,這是為了支持Java語(yǔ)言的運(yùn)行時(shí)綁定。
  (3)加載的時(shí)機(jī)沒(méi)有強(qiáng)制約束,初始化卻有,下面5種情況必須進(jìn)行立即對(duì)類(lèi)的初始化(有且只有這5種)
  1.使用new實(shí)例化對(duì)象、讀取或設(shè)置、一個(gè)類(lèi)的靜態(tài)字段(final修飾,編譯期把結(jié)果放入常量池的靜態(tài)字段除外),調(diào)用一個(gè)類(lèi)的靜態(tài)方法;
  2.使用Java.lang.reflect包的方法對(duì)類(lèi)進(jìn)行反射調(diào)用;
  3.當(dāng)初始化一個(gè)類(lèi)時(shí),該類(lèi)的父類(lèi)沒(méi)有進(jìn)行初始化,就觸發(fā)父類(lèi)初始化;
  4.當(dāng)虛擬機(jī)啟動(dòng)時(shí),用戶包含main()方法的類(lèi),虛擬機(jī)會(huì)先初始化該類(lèi);
  5.當(dāng)使用JDK 1.7的動(dòng)態(tài)語(yǔ)言支持時(shí)。
  (4)上面5中情況稱為對(duì)一個(gè)類(lèi)主動(dòng)引用,除此之外都是被動(dòng)引用
  被動(dòng)引用3個(gè)例子:
  1.通過(guò)子類(lèi)引用父類(lèi)中定義的靜態(tài)字段,只會(huì)觸發(fā)父類(lèi)初始化;
  2.new一個(gè)類(lèi)的數(shù)組,并不會(huì)觸發(fā)該類(lèi)初始化,而是初始化一個(gè)由虛擬機(jī)自動(dòng)生成,直接繼承Object的子類(lèi)。該類(lèi)代表數(shù)組元素類(lèi)型的一維數(shù)組,實(shí)現(xiàn)了數(shù)組應(yīng)有的屬性和方法,Java語(yǔ)言對(duì)數(shù)組
  的訪問(wèn)比C/C++相對(duì)安全就是因?yàn)樵擃?lèi)封裝了數(shù)組元素的訪問(wèn)方法。
  3.一個(gè)類(lèi)的靜態(tài)字段(final修飾,編譯期把結(jié)果放入常量池的靜態(tài)字段)不會(huì)被初始化
  (5)一個(gè)接口初始化時(shí)并不要求其父接口全部完成初始化,只有在真正使用到父接口的時(shí)候(如引用接口中定義的常量)才會(huì)初始化。
  3.類(lèi)加載的過(guò)程
  (1)加載
  虛擬機(jī)完成3件事
  1.通過(guò)一個(gè)類(lèi)的全限定名獲取定義此類(lèi)的二進(jìn)制字節(jié)流。
  2.將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
  3.生成一個(gè)代表該類(lèi)的java.lang.Class對(duì)象,作為方法區(qū)這個(gè)類(lèi)的各種數(shù)據(jù)訪問(wèn)入口
  加載階段是開(kāi)發(fā)人員可控性最強(qiáng)時(shí)期,可以使用用戶自定義類(lèi)加載器完成;數(shù)組類(lèi)本身不能通過(guò)類(lèi)加載器創(chuàng)建,它是由Java虛擬機(jī)直接創(chuàng)建,但數(shù)組類(lèi)的元素類(lèi)型最終還是靠類(lèi)加載器創(chuàng)建。
  加載階段完成后,虛擬機(jī)外部的二進(jìn)制字節(jié)流就按照虛擬機(jī)所需的格式存儲(chǔ)在方法區(qū)之中,然后在內(nèi)存中實(shí)例化一個(gè)java.lang.Class對(duì)象,并不一定在堆中,HotSpot虛擬機(jī)將其存放在方法區(qū)。
  加載階段與連接階段的部分內(nèi)容是交叉進(jìn)行的,加載階段尚未完成,連接階段可能已開(kāi)始。
  (2)驗(yàn)證
  確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求。Java語(yǔ)言是相對(duì)安全的語(yǔ)言,使用純粹的Java代碼無(wú)法做到諸如訪問(wèn)數(shù)組邊界以外的數(shù)據(jù),將一個(gè)對(duì)象轉(zhuǎn)型為它并未實(shí)現(xiàn)的類(lèi)型等等。如果這樣做編譯器就會(huì)拒絕編譯,但Class文件并不一定要求是就Java源碼編譯而來(lái),可以是從其他jvm上的語(yǔ)言來(lái)或者用十六進(jìn)制編輯器直接編寫(xiě)產(chǎn)生Class文件。在字節(jié)碼層面上很多Java代碼無(wú)法做到的事情是可以實(shí)現(xiàn)的,所以需要檢查輸入的字節(jié)流,驗(yàn)證就是虛擬機(jī)對(duì)自身進(jìn)行保護(hù)的工作。
  驗(yàn)證過(guò)程大致完成下面4個(gè)階段的檢驗(yàn)動(dòng)作:
  1.文件格式驗(yàn)證:
  驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范,并且能被當(dāng)前版本的虛擬機(jī)處理,比如:是否以魔數(shù)0xCAFEBABE開(kāi)頭、主次版本號(hào)是否在當(dāng)前虛擬機(jī)處理范圍、常量池中是否有不被支持的常量
  類(lèi)型等等。 只有通過(guò)這個(gè)階段的驗(yàn)證后,字節(jié)流才會(huì)進(jìn)入內(nèi)存的方法區(qū)進(jìn)行存儲(chǔ),所有后面3個(gè)階段全部是基于方法區(qū)存儲(chǔ)結(jié)構(gòu)進(jìn)行的,不會(huì)直接操作字節(jié)流。
  2.元數(shù)據(jù)驗(yàn)證:
  對(duì)字節(jié)碼描述的信息進(jìn)行語(yǔ)義分析,以保證其描述的信息符合Java語(yǔ)言規(guī)范,比如:是否有父類(lèi)(除了java.lang.Object之外所有類(lèi)要有父類(lèi))、是的繼承了不該繼承的類(lèi)(final)、如果不是抽
  象類(lèi)是否實(shí)現(xiàn)了其父類(lèi)或接口中的所有要實(shí)現(xiàn)的方法。
  3.字節(jié)碼原則:
  主要目的通過(guò)數(shù)據(jù)流和控制流分析,確定程序語(yǔ)義是合法、符合邏輯的。在第二階段對(duì)元信息中的數(shù)據(jù)類(lèi)型做完校驗(yàn)后,這個(gè)階段將對(duì)類(lèi)的方法體進(jìn)行校驗(yàn)分析,保證被校驗(yàn)類(lèi)的方法在運(yùn)行時(shí)
  不會(huì)做出危害虛擬機(jī)安全的事件。比如:保證任意時(shí)刻操作數(shù)棧的數(shù)據(jù)類(lèi)型與指令代碼序列都能配合工作、保證跳轉(zhuǎn)指令不會(huì)跳轉(zhuǎn)到方法體以外的字節(jié)碼等等。
  4.符號(hào)引用驗(yàn)證:
  這一階段發(fā)生在虛擬機(jī)將符號(hào)引用轉(zhuǎn)化為直接引用的時(shí)候,也就是在解析階段發(fā)生。通常需要校驗(yàn)的內(nèi)容有:符號(hào)引用中通過(guò)字符串描述的全限定名是否能找到對(duì)應(yīng)的類(lèi)、符號(hào)引用中類(lèi)的訪問(wèn)
  性是否能被當(dāng)前類(lèi)訪問(wèn)。
  (3)準(zhǔn)備
  準(zhǔn)備階段是正式為類(lèi)變量分配內(nèi)存并設(shè)置類(lèi)變量初始化值,這些變量使用的內(nèi)存都將在方法區(qū)中分配,初始化值為零值。注意該階段進(jìn)行內(nèi)存分配的僅包括類(lèi)變量(static),不包括實(shí)例變量,實(shí)例變量將在對(duì)象實(shí)例化時(shí)隨對(duì)象一起分配在堆中。
  (4)解析,將虛擬機(jī)將常量池內(nèi)的符號(hào)引用替換為直接引用的過(guò)程
  (5)初始化,初始化階段真正開(kāi)始執(zhí)行類(lèi)中定義的Java程序代碼,對(duì)類(lèi)變量初始化用戶定義的值
  4.類(lèi)加載器
  (1)執(zhí)行通過(guò)一個(gè)類(lèi)的全限定名獲取描述此類(lèi)的二進(jìn)制流,該動(dòng)作放在Java虛擬機(jī)外部實(shí)現(xiàn)
  (2)對(duì)于任意一個(gè)類(lèi),都需要由加載它的類(lèi)加載期和這個(gè)類(lèi)本身一同確定其在Java虛擬機(jī)中的唯一性,每個(gè)類(lèi)加載器都有一個(gè)獨(dú)立的類(lèi)名稱空間
  (3)比較兩個(gè)類(lèi)是否相等:Class對(duì)象equals()方法、isAssignableFrom()、isInstance()的返回結(jié)果,只有在兩個(gè)類(lèi)由同一個(gè)類(lèi)加載器加載的前提下才有意義。
  (5)類(lèi)加載器類(lèi)型:
  1.從Java虛擬機(jī)的角度來(lái)講,只存在兩種兩種不同的類(lèi)加載器:?jiǎn)?dòng)類(lèi)加載器,虛擬機(jī)自身的一部分;其他類(lèi)加載器,獨(dú)立于虛擬機(jī)外部。
  2.從開(kāi)發(fā)人員角度:
  啟動(dòng)類(lèi)加載器:負(fù)責(zé)將JAVA_HOME/lib目錄中的,或者被-Xbootclasspath參數(shù)指定的路徑中的,并能被虛擬機(jī)識(shí)別的類(lèi)庫(kù)加載到內(nèi)存,啟動(dòng)類(lèi)加載器無(wú)法被Java程序無(wú)法直接引用。
  擴(kuò)展類(lèi)加載器:負(fù)責(zé)加載JAVA_HOME/lib/ext目錄中,或者被java.ext.dirs系統(tǒng)變量指定的路徑中的所有類(lèi)庫(kù),開(kāi)發(fā)人員可直接使用。
  應(yīng)用程序類(lèi)加載器(系統(tǒng)類(lèi)加載器):負(fù)責(zé)用戶類(lèi)路徑(classpath)上指定的類(lèi)庫(kù),可直接使用,如果應(yīng)用程序沒(méi)有自定義過(guò)自己的類(lèi)加載器一般就用程序默認(rèn)的類(lèi)加載器。
  (6)雙親委派模型
  該模型要求除了頂層的啟動(dòng)類(lèi)加載器,其余的類(lèi)加載器都應(yīng)當(dāng)有自己的父類(lèi)加載器,父子關(guān)系不是通過(guò)繼承的關(guān)系來(lái)實(shí)現(xiàn),而是通過(guò)組合關(guān)系來(lái)復(fù)用父加載器。
  過(guò)程:如果一個(gè)類(lèi)加載器收到類(lèi)加載的請(qǐng)求,他首先不會(huì)自己去嘗試,而是委派父類(lèi)加載器去完成,每一層都是如此,因此所有的加載請(qǐng)求都會(huì)傳到頂層的啟動(dòng)類(lèi)加載器,只有當(dāng)父加載器反饋?zhàn)约簾o(wú)法加載時(shí),子加載器才嘗試自己加載。
  好處:Java類(lèi)隨它的類(lèi)加載器而具有一種優(yōu)先級(jí)的層次關(guān)系。比如java.lang.Object無(wú)論誰(shuí)去加載它都會(huì)是同一個(gè)類(lèi)(不同類(lèi)加載器有其獨(dú)立的類(lèi)名稱空間,只有在兩個(gè)類(lèi)由同一個(gè)類(lèi)加載器加載的前提下才有意義),如果各自加載又會(huì)有多個(gè)Object類(lèi),Java類(lèi)型體系中最基礎(chǔ)的行為也就無(wú)法保證。
  (7)破壞雙親委派模型
  Java不提倡用戶再去覆蓋loadClass()方法,而是把自己的類(lèi)加載邏輯寫(xiě)入findClass()方法中,loadClass()邏輯是如果父加載器加載失敗,就調(diào)用自己的findClass()方法來(lái)完成加載。
以上就是虛擬機(jī)的加載機(jī)制。

免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認(rèn)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請(qǐng)發(fā)送郵件至:operations@xinnet.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

免費(fèi)咨詢獲取折扣

Loading
主站蜘蛛池模板: 一本之道高清无码视频 | 国产精品久久午夜 | 国产一级影院 | 亚洲激情校园 | 蜜臀av免费一区二区三区水牛 | 绝顶高潮videos | 麻豆视频在线免费看 | 少妇把腿扒开让我添69 | 5x免费视频| 久久精品视频在线观看 | 欧美大黄大色一级毛片 | 日本一区二区免费在线播放 | 国产一区在线看 | 精品一区二区中文字幕 | 久久久久国产精品一区二区三区 | 色窝窝无码精品一区二区 | 亚洲第一成网 | aaa一级毛片 | 国产欧美久久一区二区三区 | 国产中文字幕在线播放 | 少妇一级淫片 | 男人插女人逼逼视频 | 一级二级视频免费观看 | 夜夜调教禁脔欢爱h | 成人综合在线观看视频 | 精品国产免费久久久久久尖叫 | 2023国精产品一二二线免费 | 中国一级毛片免费看 | 狠狠躁夜夜躁人人躁婷婷视频 | 久久综合99re88久久爱 | 久久久com| 人人干日日操 | 毛茸茸xxxxx 中文字幕亚洲码在线观看 99国产免费网址 | 凌晨三点免费视频www | 国产亚洲精品AA片在线不卡 | 亚洲精品无码一区二区三区污 | 亚洲AV永久无码精品三区在线4 | 国产精品老牛影院av | 免费观看一级 | 亚洲欧洲精品一区二区三区 | 久久综合免费视频影院 |