JVM類加載機制

Java的程序要運行須要將編譯好的class文件加載到JVM運行時數據區。java

img

在瞭解類的加載機制以前,咱們須要瞭解一下類的生命週期。Java類從被加載到JVM內存開始,到卸載出內存爲止,它的整個生命週期包括了:加載(Loading),驗證(Verification),準備(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸載(Unloading)七個階段。安全

img

類加載器

Java類的加載須要用到類加載器。類加載器負責裝入類,搜索網絡,jar,zip,文件夾,二進制數據,內存等指定位置的資源。一個Java程序運行,至少有3個不一樣的類加載器實例,負責加載不一樣的類。這三個類加載器分別爲,啓動類加載器(Bootstrap ClassLoader),擴展類加載器(Extension ClassLoader),應用程序類加載器(Application ClassLoader)。markdown

img

經過JDK提供的API:java.lang.Class.getClassLoader() 能夠進行類加載器的查看,該API會返回裝載類的類加載器,若是這個類是由Bootstrap ClassLoader加載的,那個這個方法會返回null。網絡

代碼示例:app

public class ClassLoaderView {

  public static void main(String[] args) throws Exception {
    // 加載核心類庫的 BootStrap ClassLoader
    System.out.println(
        "核心類庫加載器:"
            + ClassLoaderView.class
                .getClassLoader()
                .loadClass("java.lang.String")
                .getClassLoader());

    // 加載拓展庫的 Extension ClassLoader
    System.out.println(
        "拓展類庫加載器:"
            + ClassLoaderView.class
                .getClassLoader()
                .loadClass("com.sun.nio.zipfs.ZipCoder")
                .getClassLoader());

    // 加載應用程序的 Application ClassLoader
    System.out.println("應用程序庫加載器:" + ClassLoaderView.class.getClassLoader());
  }
}

//運行結果:
核心類庫加載器:null
拓展類庫加載器:sun.misc.Launcher$ExtClassLoader@7f31245a
應用程序庫加載器:sun.misc.Launcher$AppClassLoader@18b4aac2

JVM如何知道咱們的類在何方

class信息能夠存在不一樣的地方,那麼JVM是如何知道咱們的類存在什麼地方的哪?經過查看sun.misc.Launcher.AppClassLoader的源碼咱們能夠看到,它會讀取java.class.path這個配置來獲取那些地址加載類資源。參考如下代碼示例,利用jsp和jcmd兩個命令能夠進行驗證。jvm

代碼示例:jsp

public class HelloWord {

  public static void main(String[] args) throws IOException {
    System.out.println("Hello Word");
    System.in.read();
  }
}

jsp命令能夠查看本機Java進程,jcmd命令能夠查看運行時配置:jcmd 進程號 VM.system_propertiesui

img

雙親委派模型

Java中的類並不會重複加載,同一類加載器,同一類名,表明的是同一個類。而避免類重複加載的主要緣由在於JVM在加載類時默認採用的是雙親委派模型。所謂的雙親委派模型,就是某個特定的類加載器在接到類的加載請求時,首先將加載任務委託給父加載器,依次遞歸,若是父加載器能夠完成類加載任務,就成功返回;只有父加載器沒法完成此加載任務時,才本身去加載。由下到上逐級委託,由上到下逐級查找,雙親委派模型保證了Java核心庫的類型安全url

img

類的卸載

JVM中的類不可能一直存在,在知足必定條件的狀況下類會被卸載掉。在知足該Class的全部實例都已被垃圾回收,同時加載該類的ClassLoader實例也已經被垃圾回收,那麼這個類會被JVM卸載掉。在JVM啓動中增長-verbose:class參數,能夠輸出類加載和卸載的日誌信息。spa

相關文章
相關標籤/搜索