深入理解JVM虚拟机笔记——类加载机制
深入理解JVM虛擬機(jī)筆記——類(lèi)加載機(jī)制
boot類(lèi)加載器:加載jre/lib 下的jar/class
ext類(lèi)加載器:加載jre/lib/ext 下的jar/class
app類(lèi)加載器:加載自己應(yīng)用程序下的jar/class(如target編譯文件目錄)
為什么要設(shè)計(jì)雙親委派機(jī)制?
1:沙箱保護(hù)機(jī)制:比如自己寫(xiě)的java.lang.String不會(huì)生效
2:避免類(lèi)的重復(fù)加載,保證了被加載類(lèi)的唯一性(loadClass方法有做非空判斷)
自定義類(lèi)加載器:
只需要繼承ClassLoad類(lèi)重寫(xiě)findClass方法把自己的類(lèi)庫(kù)轉(zhuǎn)為字節(jié)數(shù)組調(diào)用defineClass方法轉(zhuǎn)為Class返回就好了,甚至可以重寫(xiě)loadClass打破雙親委派機(jī)制。
loadClass加載類(lèi)時(shí)會(huì)做以下幾個(gè)過(guò)程:
加載-驗(yàn)證-準(zhǔn)備-解析-初始化
加載:把類(lèi)通過(guò)io讀入字節(jié)碼文件,在堆中生成這個(gè)類(lèi)的java.lang.Class到內(nèi)存中
驗(yàn)證:校驗(yàn)字節(jié)碼文件的正確性
準(zhǔn)備:給靜態(tài)變量賦默認(rèn)值并分配內(nèi)存。int默認(rèn)值是0 對(duì)象默認(rèn)值是null 布爾類(lèi)型默認(rèn)值是false
解析:把靜態(tài)符號(hào)引用轉(zhuǎn)換為直接引用(內(nèi)存地址),比如a.hello() 這個(gè)a和 hello都是符號(hào)引用,這時(shí)會(huì)把hello轉(zhuǎn)為直接引用(內(nèi)存地址)這樣就能找到這個(gè)hello()具體的代碼從而去執(zhí)行。
初始化:把靜態(tài)變量賦指定值(這時(shí)賦的值才是我們程序員寫(xiě)的值)然后執(zhí)行靜態(tài)代碼塊。
類(lèi)被加載后會(huì)把一系列的信息放到方法區(qū)(如運(yùn)行時(shí)常量池,方法信息,字段信息,類(lèi)加載器的引用,對(duì)應(yīng)class實(shí)例的引用)
class實(shí)例的引用指的是被加載類(lèi)會(huì)實(shí)例出java.lang.Class的對(duì)象實(shí)例到堆中。作為方法區(qū)類(lèi)定義的入口
總結(jié)
類(lèi)加載運(yùn)行全過(guò)程:
首先windows系統(tǒng)下java.exe調(diào)用jvm.dld文件創(chuàng)建java虛擬機(jī)(c++實(shí)現(xiàn)),jvm會(huì)創(chuàng)建好boot類(lèi)加載器,然后創(chuàng)建launcher實(shí)例,在launcher類(lèi)構(gòu)造方法中創(chuàng)建了兩個(gè)類(lèi)加載器,第一個(gè)是ext類(lèi)加載器,第二個(gè)是app類(lèi)加載器 得到classload,然后調(diào)用loadclass方法加載這個(gè)加載器下的所有類(lèi),loadclass方法首先會(huì)去判斷有沒(méi)有之前是不是已經(jīng)加載過(guò)這個(gè)類(lèi),如果沒(méi)有加載過(guò)就會(huì)去調(diào)用parent加載器也就是他的父類(lèi)加載器ext,ext同樣調(diào)用loadclass 然后又去找自己的parent加載器boot加載器。因?yàn)閎oot類(lèi)加載器是最大的加載器沒(méi)有父加載器了,所以會(huì)去判斷這個(gè)加載器有沒(méi)有這個(gè)類(lèi)如果沒(méi)有這個(gè)類(lèi)就會(huì)再依次回到子加載器去加載這個(gè)類(lèi),如果子類(lèi)加載器找到了這個(gè)類(lèi)則調(diào)用findClass方法來(lái)完成類(lèi)的加載。
總結(jié)
以上是生活随笔為你收集整理的深入理解JVM虚拟机笔记——类加载机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 淘宝开发平台 java 调用实例
- 下一篇: 如何在chrome加载.ctx文件(亲测