全部的編譯生成的.class文件都會被直接加載到JVM裏面來嗎**(並不**html
首先咱們明確一個概念,.class文件加載到jvm中意味着什麼——類的初始化java
在虛擬機規範中,咱們規定,有且只有五種狀況必須當即對類進行初始化git
.class的加載是消耗內存的,因此固然不能一次性的把全部的類加載再運行(原本就不快,這樣作不是更慢),程序的base class會徹底加載到jvm裏面來,至於其餘的類,它們都是在須要的時候再加載的,這樣是爲了節省內存開銷。github
class是經過類的加載器裝在到jvm裏面來的,Java默認有三種類加載器web
java.lang.ClassLoader
。ClassLoader.getSystemClassLoader()
來獲取它。 雙親委派模型apache
若是一個類收到了加載的請求,它首先不會本身加載這個類,而是會把請求委託給父加載器去完成,依次向上。(若是自身完成不了再依次向下,直到拋出ClassNotFound異常)bootstrap
advantage:緩存
防止內存中出現多份一樣的字節碼(從安全性角度來講)tomcat
class loader在成功加載某個類以後,會把獲得的java.lang.Class類的實例緩存起來。若是下次再遇見該類的加載請求,類加載器會直接使用緩存的類的實例,不會再次加載。安全
俄羅斯套娃
類加載器的Java類和全部其餘的Java類同樣,都是要經過類加載器來加載的。
對於開發人員編寫的類加載器來講,父類是加載該類加載器的Java類的類加載器
加載器加載到jvm中,接下來其實又分了好幾個步驟:
對於運行在 Java EE™容器中的 Web 應用來講,類加載器的實現方式與通常的 Java 應用有所不一樣。不一樣的 Web 容器的實現方式也會有所不一樣。以 Apache Tomcat 來講,每一個 Web 應用都有一個對應的類加載器實例。該類加載器也使用代理模式,所不一樣的是它是首先嚐試去加載某個類,若是找不到再代理給父類加載器。這與通常類加載器的順序是相反的。這是 Java Servlet 規範中的推薦作法,其目的是使得 Web 應用本身的類的優先級高於 Web 容器提供的類。這種代理模式的一個例外是:Java 核心庫的類是不在查找範圍以內的。這也是爲了保證 Java 核心庫的類型安全。
In a Java environment, class loaders are arranged in a parent-child tree. Normally, when a class loader is asked to load a particular class or resource, it delegates the request to a parent class loader first, and then looks in its own repositories only if the parent class loader(s) cannot find the requested class or resource. Note, that the model for web application class loaders differs slightly from this, as discussed below, but the main principles are the same.
When Tomcat is started, it creates a set of class loaders that are organized into the following parent-child relationships, where the parent class loader is above the child class loader:
Bootstrap | System | Common / \ Webapp1 Webapp2 ...
Therefore, from the perspective of a web application, class or resource loading looks in the following repositories, in this order:
Bootstrap classes of your JVM /WEB-INF/classes of your web application /WEB-INF/lib/.jar of your web application System class loader classes (described above) Common class loader classes (described above)
If the web application class loader is configured with <Loader delegate="true"/> then the order becomes:*
Bootstrap classes of your JVM System class loader classes (described above) Common class loader classes (described above) /WEB-INF/classes of your web application /WEB-INF/lib/.jar of your web application
絕大多數狀況下,Web 應用的開發人員不須要考慮與類加載器相關的細節。下面是幾條簡單的原則:
- 每一個 Web 應用本身的 Java 類文件和使用的庫的 jar 包,分別放在
WEB-INF/classes
和WEB-INF/lib
目錄下面。- 多個應用共享的 Java 類文件和 jar 包,分別放在 Web 容器指定的由全部 Web 應用共享的目錄下面。
- 當出現找不到類的錯誤時,檢查當前類的類加載器和當前線程的上下文類加載器是否正確。
ps.用的圖牀掛了,你們先將就着看下,後續再改
跟着博客作的一個ClassLoader小demo https://github.com/JhinQaQ/Classloader
Java虛擬機底層原理知識總結 https://github.com/doocs/jvm
tomcat7.0 ClassLoader http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html
深刻探討Java類加載器 https://www.ibm.com/developerworks/cn/java/j-lo-classloader/
Java類加載器的使用場景有哪些?https://www.zhihu.com/question/46719811