資料內(nèi)容:
2. 什么是類(lèi)加載器?
ClassLoader oader = ClassName.class.getClassLoader();
ClassLoader ParentLoader = loader.getParent();
類(lèi)加載器是一個(gè)用來(lái)加載類(lèi)文件的類(lèi)。Java源代碼通過(guò)javac編譯器編譯成類(lèi)文件。然后JVM來(lái)執(zhí)行類(lèi)文件中
的字節(jié)碼來(lái)執(zhí)行程序。類(lèi)加載器負(fù)責(zé)加載文件系統(tǒng)、網(wǎng)絡(luò)或其他來(lái)源的類(lèi)文件。
3. 類(lèi)加載器有哪些?
有三種默認(rèn)使用的類(lèi)加載器:Bootstrap類(lèi)加載器、Extension類(lèi)加載器和Application類(lèi)加載器。每種類(lèi)加載
器都有設(shè)定好從哪里加載類(lèi)。
Bootstrap類(lèi)加載器負(fù)責(zé)加載rt.jar中的JDK類(lèi)文件,它是所有類(lèi)加載器的父加載器。Bootstrap類(lèi)加載器沒(méi)有
任何父類(lèi)加載器,如果你調(diào)用String.class.getClassLoader(),會(huì)返回null,任何基于此的代碼會(huì)拋出
NullPointerException異常。Bootstrap加載器被稱(chēng)為初始類(lèi)加載器。
而Extension將加載類(lèi)的請(qǐng)求先委托給它的父加載器,也就是Bootstrap,如果沒(méi)有成功加載的話,再?gòu)?br />
jre/lib/ext目錄下或者java.ext.dirs系統(tǒng)屬性定義的目錄下加載類(lèi)。Extension加載器由
sun.misc.Launcher? ExtClassLoader實(shí)現(xiàn)。
第三種默認(rèn)的加載器就是Application類(lèi)加載器了。它負(fù)責(zé)從classpath環(huán)境變量中加載某些應(yīng)用相關(guān)的類(lèi),
classpath環(huán)境變量通常由-classpath或-cp命令行選項(xiàng)來(lái)定義,或者是JAR中的Manifest的classpath屬性。
Application類(lèi)加載器是Extension類(lèi)加載器的子加載器。通過(guò)sun.misc.Launcher? AppClassLoader實(shí)現(xiàn)。
4. 什么是雙親委派模型(Parent-Delegation
Model)?
JVM中加載類(lèi)機(jī)制采用的是雙親委派模型,顧名思義,在該模型中,子類(lèi)加載器收到的加載請(qǐng)求,不會(huì)先去
處理,而是先把請(qǐng)求委派給父類(lèi)加載器處理,當(dāng)父類(lèi)加載器處理不了時(shí)再返回給子類(lèi)加載器加載;
5. 為什么使用雙親委派模型?
因?yàn)榘踩J褂秒p親委派模型來(lái)組織類(lèi)加載器間的關(guān)系,能夠使類(lèi)的加載也具有層次關(guān)系,這樣能夠保證核
心基礎(chǔ)的Java類(lèi)會(huì)被根加載器加載,而不會(huì)去加載用戶自定義的和基礎(chǔ)類(lèi)庫(kù)相同名字的類(lèi),從而保證系統(tǒng)的
有序、安全。
6. Java內(nèi)存分配基本概念
每運(yùn)行一個(gè)java程序會(huì)產(chǎn)生一個(gè)java進(jìn)程,每個(gè)java進(jìn)程可能包含一個(gè)或者多個(gè)線程,每一個(gè)Java進(jìn)程對(duì)應(yīng)唯
一一個(gè)JVM實(shí)例,每一個(gè)JVM實(shí)例唯一對(duì)應(yīng)一個(gè)堆,每一個(gè)線程有一個(gè)自己私有的棧。進(jìn)程所創(chuàng)建的所有類(lèi)的
實(shí)例(也就是對(duì)象)或數(shù)組(指的是數(shù)組的本身,不是引用)都放在堆中,并由該進(jìn)程所有的線程共享。Java
中分配堆內(nèi)存是自動(dòng)初始化的,即為一個(gè)對(duì)象分配內(nèi)存的時(shí)候,會(huì)初始化這個(gè)對(duì)象中變量。雖然Java中所有
對(duì)象的存儲(chǔ)空間都是在堆中分配的,但是這個(gè)對(duì)象的引用卻是在棧中分配,也就是說(shuō)在建立一個(gè)對(duì)象時(shí)在堆和
棧中都分配內(nèi)存,在堆中分配的內(nèi)存實(shí)際存放這個(gè)被創(chuàng)建的對(duì)象的本身,而在棧中分配的內(nèi)存只是存放指向
這個(gè)堆對(duì)象的引用而已。局部變量 new 出來(lái)時(shí),在??臻g和堆空間中分配空間,當(dāng)局部變量生命周期結(jié)束
后,??臻g立刻被回收,堆空間區(qū)域等待GC回收。
具體的概念:JVM的內(nèi)存可分為3個(gè)區(qū):堆(heap)、棧(stack)和方法區(qū)(method,也叫靜態(tài)區(qū)):
堆區(qū):存儲(chǔ)的全部是對(duì)象,每個(gè)對(duì)象都包含一個(gè)與之對(duì)應(yīng)的class的信息(class的目的是得到操作指令) ;jvm
只有一個(gè)堆區(qū)(heap),且被所有線程共享,堆中不存放基本類(lèi)型和對(duì)象引用,只存放對(duì)象本身和數(shù)組本身;
棧區(qū):每個(gè)線程包含一個(gè)棧區(qū),棧中只保存基礎(chǔ)數(shù)據(jù)類(lèi)型本身和自定義對(duì)象的引用;每個(gè)棧中的數(shù)據(jù)(原始類(lèi)
型和對(duì)象引用)都是私有的,其他棧不能訪問(wèn);棧分為3個(gè)部分:基本類(lèi)型變量區(qū)、執(zhí)行環(huán)境上下文、操作指
令區(qū)(存放操作指令);
方法區(qū)(靜態(tài)區(qū)):
被所有的線程共享,方法區(qū)包含所有的class(class是指類(lèi)的原始代碼,要?jiǎng)?chuàng)建一個(gè)類(lèi)的對(duì)象,首先要把該類(lèi)
的代碼加載到方法區(qū)中,并且初始化)和static變量。方法區(qū)中包含的都是在整個(gè)程序中永遠(yuǎn)唯一的元素,如
class,static變量。