成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java類加載相關(guān)

el09xccxy / 2121人閱讀

摘要:標(biāo)準(zhǔn)擴展類加載器,它負(fù)責(zé)加載或由系統(tǒng)變量指定位置中的類庫加載到內(nèi)存中。系統(tǒng)類加載器,它負(fù)責(zé)將類路徑中的類庫加載到內(nèi)存。

類加載機制大家應(yīng)該已經(jīng)非常熟悉了,采取雙親委派機制,當(dāng)加載一個類時,首先將加載任務(wù)委托給父類加載器,依次遞歸,如果父類加載器可以完成加載任務(wù),就成功返回;如果父類無法加載,才由自己加載。

雙親委派機制的作用:防止內(nèi)存中出現(xiàn)多份相同的字節(jié)碼。

其他規(guī)則
1.隱式加載:在當(dāng)前類中所有new的對象,如果沒有被加載,則使用當(dāng)前類的類加載器加載 如果類A中引用了類B,Java虛擬機將使用加載類A的類加載器去加載類B
2.不同類加載器加載的類是不同的,通過類加載器+類全路徑來唯一標(biāo)識一個類

JVM預(yù)定義的三種類加載器
1.Bootstrap ClassLoader:啟動類加載器,它負(fù)責(zé)將JAVA_HOME/lib下面的類庫加載到內(nèi)存中,如rt.jar;啟動類加載器是由C++寫的二進制代碼,不是java類,在JVM啟動的時候Bootstrap就已經(jīng)啟動。
2.Extension ClassLoader:標(biāo)準(zhǔn)擴展類加載器,它負(fù)責(zé)加載JAVA_HOME/lib/ext或由系統(tǒng)變量java.ext.dir指定位置中的類庫加載到內(nèi)存中。
3.APP ClassLoader:系統(tǒng)類加載器(System ClassLoader),它負(fù)責(zé)將類路徑CLASSPATH中的類庫加載到內(nèi)存。

加載順序圖如下:

圖中的BootStrapClassLoader、ExtClassLoader、APPClassLoader不是真正的繼承關(guān)系,只是邏輯上的上下級類加載器;

實際上的類關(guān)系如下圖:

可以看到ExtClassLoader和APPCLassLoader都繼承自URLClassLoader,也就證實了二者并非真正的繼承關(guān)系;

通過上圖可以看到最頂層的類是抽象類ClassLoader:是所有類加載器的基類(除了啟動類加載器),定義了類加載最核心的操作;
SecureClassLoader:添加了關(guān)聯(lián)類源碼、關(guān)聯(lián)系統(tǒng)權(quán)限支持
URLClassLoader:支持從jar文件和文件夾中獲取class
ExtClassLoader:擴展類加載器Extension ClassLoader
APPClassLoader:系統(tǒng)類加載器,也稱為System ClassLoader

ClassLoader:

父子類加載器是通過ClassLoader一個parent屬性來標(biāo)識,APPClassLoader的父加載器是ExtClassLoader,ExtClassLoader的父加載器是null。

ClassLoader提供了兩個構(gòu)造器,一個是沒有參數(shù)的,一個是有參數(shù)的;如下圖:

沒有參數(shù)的構(gòu)造器默認(rèn)將系統(tǒng)類加載器作為parent加載器;
有參數(shù)的構(gòu)造器將參數(shù)指定的加載器作為父類加載器;

Launcher:

ExtClassLoader和AppClassLoader都是Launcher的子類,在ClassLoader初始化或者直接通過ClassLoader的getSystemClassLoader()獲取的時候會調(diào)用initSystemClassLoader(),從而調(diào)用sun.misc.Launcher.getLauncher(),將系統(tǒng)類加載器賦值給ClassLoader的scl變量;

我們看下Launcher類初始化的時候都做了什么工作,如圖:

主要是三部工作:
1.創(chuàng)建ExtClassLoader
2.創(chuàng)建AppClassLoader
3.將線程系統(tǒng)類加載器設(shè)置為線程上下文類加載器,什么是上線文類加載器?

線程上下文類加載器
java提供了為很多服務(wù)商提供了接口,簡稱SPI(Service Provider Interface),具體的實現(xiàn)由各廠商提供,例如mysql驅(qū)動,oracle驅(qū)動等。例如:mysql驅(qū)動加載接口類在rt.jar中,由啟動類加載器加載,具體實現(xiàn)類在mysql驅(qū)動包中,驅(qū)動包一般放到我們自己的程序路徑lib下,應(yīng)該由系統(tǒng)類加載器加載;但是在使用如下代碼進行數(shù)據(jù)庫連接使用操作的時候,就會出現(xiàn)在rt.jar中要加載驅(qū)動包里代碼的情況(類加載器是啟動類加載器),由隱式加載規(guī)則可知,驅(qū)動包也要使用啟動類加載器加載,由類加載機制可知,是無法通過啟動類加載器來加載的;那這種情況怎么辦呢,就要通過線程上下文類加載器來解決。

上面描述的情況如下:使用jdbc進行數(shù)據(jù)庫操作如下

1.Class.forName("com.mysql.jdbc.Driver");// 加載mysql驅(qū)動
2.Connection conn = DriverManager.getConnection(url);//創(chuàng)建連接
3.Statement stmt = conn.createStatement();//得到statement對象
4.操作數(shù)據(jù)庫  關(guān)閉連接。。

第一步在實例化Driver時,會調(diào)用DriverManager的registerDriver()方法收集divers,將驅(qū)動類注冊到DriverManager容器中,DriverManage的drivers容器:

注冊的代碼:

Class.forName("com.mysql.jdbc.Driver")相當(dāng)于:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class driversClass = loader.loadClass("com.mysql.jdbc.Driver");
driversClass.newInstance();
由此可見com.mysql.jdbc.Driver是由我們自己應(yīng)用類加載器AppClassLoader進行加載;

第二步通過DriverManager.getConnection(url),會循環(huán)獲取drivers中的driver,調(diào)用具體driver實現(xiàn)里的cnnect()方法,進行連接

caller.getClassLoader()是啟動類加載器為null,因此callerCL為系統(tǒng)類加載器

getConnection通過isDriverAllowed方法校驗類是否有權(quán)限被加載

通過AppClassLoader來加載Driver看是否和已注冊的Driver是同一個類,如果是則調(diào)用driver的connect方法

在java6以后,引入了service provider概念,在/META-INF/services/java.sql.Driver文件中配置需要加載的驅(qū)動類,
在DriverManager初始化的時候會調(diào)用loadInitialDrivers方法,

會使用AppClassLoader進行加載,所以在自己程序中可以不用Class.forName顯示調(diào)用。

上面包類結(jié)構(gòu)如下圖:

tomcat類加載
我們運行tomcat的多個實例,不想安裝tomcat軟件副本,我們可以配置多個工作目錄,每個運行實例獨占一個工作目錄,但是共享一個安裝目錄。
變量解釋:
CATALINA_HOME:tomcat安裝目錄,多個工作目錄可共享安裝目錄
CATALINA_BASE:tomcat工作目錄,tomcat每個運行實例需要使用自己的conf、logs、temp、webapps、work、shared目錄,CATALINA_BASE就是指向這個目錄

如下圖:兩個應(yīng)用公用CATALINA_HOME,CATALINA_BASE指向各自工作目錄


首先看下tomcat在啟動時類初始化類加載器過程

首先是創(chuàng)建commonClassLoader,commonClassLoader加載的是配置文件catalina.properties中配置的

common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar
server.loader=
shared.loader=
例如在我們的服務(wù)器上路徑是:
/opt/soft/tomcat/lib、/opt/soft/tomcat/lib/*.jar

因為server.loader和shared.loader未配置具體加載目錄信息,catalinaLoader和sharedLoader默認(rèn)為commonLoader(在tomcat5以后catalinaLoader和sharedLoader默認(rèn)不啟用)

tomcat一共定義了兩種類加載器
StandardClassLoader:實例化commonloader、catalinaLoader、sharedLoader,不提供熱部署功能,遵循雙親委派機制
WebappClassLoader:和context級容器相關(guān)聯(lián),加載web程序,支持其加載路徑下資源改變后重新加載,不遵循雙親委派機制。

其類繼承關(guān)系如下:

除此之外還有兩個類:WebappLoader和VirtualWebappLoader,該兩個類不是類加載器,只是對WebappClassLoader做了封裝,對熱部署、生命周期控制等功能做了一些控制;
VirtualWebappLoader是WebappLoader的子類,主要是和conf/context.xml這個文件相關(guān)聯(lián),主要功能是加載context.xml配置文件中設(shè)置的一些java類庫,由于WebappClassLoader只能加載WEB-INF/class和WEB-INF/lib下的類庫。而想擴展一下加載路徑又不想添加到WEB-INF/lib中的時候,可以配置在context.xml文件中。

自己實現(xiàn)類記載器只要實現(xiàn)findclass即可,這里為了實現(xiàn)特殊目的而override了loadClass();WebappClassLoader重寫了loadClass方法,先自己加載,如果加載不了再進行其他操作。

所以在Tomcat 6中默認(rèn)情況下,不是完全按照先Tomcat的lib再Web應(yīng)用的lib這種順序去加載類。
Jar包的加載順序是:
1)JRE中的Java基礎(chǔ)包
2)Web應(yīng)用WEB-INF/lib下的包
3)Tomcat/lib下的包

如果想要在Web應(yīng)用間共享一些Jar包,則不僅需要將公共包放在Tomcat的lib下,還要刪掉Web應(yīng)用lib中的包,否則Tomcat啟動時還是會優(yōu)先加載Web應(yīng)用lib下的包的。

如果想要自己指定一個Tomcatlib和Web應(yīng)用lib之外的ClassPath,除了修改Tomcat啟動腳本外,可以為不同Web應(yīng)用的Context指定一個VirtualWebappLoader,但源碼注釋中寫到不推薦在生產(chǎn)環(huán)境中使用。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70300.html

相關(guān)文章

  • 我的面試準(zhǔn)備過程--JVM相關(guān)

    摘要:程序計數(shù)器程序計數(shù)器是一塊較小的內(nèi)存空間,它的作用可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。它的主要缺點有兩個一個是效率問題,標(biāo)記和清除過程的效率都不 Jvm 相關(guān)  類加載機制 本段參考 http://www.importnew.com/2374... 類加載概念 類加載指的是將類的.class文件中的二進制數(shù)據(jù)讀入到內(nèi)存中,將其放在運行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi),然后在堆區(qū)創(chuàng)建一個ja...

    Towers 評論0 收藏0
  • Java 虛擬機總結(jié)給面試的你(中)

    摘要:驗證過程驗證過程的目的是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機的要求,并且不會危害虛擬機自身的安全。二虛擬機字節(jié)碼執(zhí)行引擎虛擬機的執(zhí)行引擎自行實現(xiàn),可以自行制定指令集與執(zhí)行引擎的結(jié)構(gòu)體系。 本篇博客主要針對Java虛擬機的類加載機制,虛擬機字節(jié)碼執(zhí)行引擎,早期編譯優(yōu)化進行總結(jié),其余部分總結(jié)請點擊Java虛擬總結(jié)上篇 。 一.虛擬機類加載機制 概述 虛擬機把描述類的數(shù)據(jù)從Clas...

    MRZYD 評論0 收藏0
  • Java魔法——Unsafe應(yīng)用解析

    摘要:典型應(yīng)用鎖和同步器框架的核心類,就是通過調(diào)用和實現(xiàn)線程的阻塞和喚醒的,而的方法實際是調(diào)用的方式來實現(xiàn)。 前言 Unsafe是位于sun.misc包下的一個類,主要提供一些用于執(zhí)行低級別、不安全操作的方法,如直接訪問系統(tǒng)內(nèi)存資源、自主管理內(nèi)存資源等,這些方法在提升Java運行效率、增強Java語言底層資源操作能力方面起到了很大的作用。但由于Unsafe類使Java語言擁有了類似C語言指針...

    reclay 評論0 收藏0
  • Java虛擬機加載過程

    摘要:二驗證驗證主要是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機的要求,并且不會危害虛擬機的自身安全。五初始化類的初始化階段是類加載過程的最后一步,該階段才真正開始執(zhí)行類中定義的程序代碼或者說是字節(jié)碼。 關(guān)注我,每天三分鐘,帶你輕松掌握一個Java相關(guān)知識點。 虛擬機(JVM)經(jīng)常出現(xiàn)在我們面試中,但是工作中卻很少遇到,導(dǎo)致很多同學(xué)沒有去了解過。其實除了應(yīng)付面試,作為java程序員,了解...

    lentoo 評論0 收藏0

發(fā)表評論

0條評論

el09xccxy

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<