重學JVM之類加載機制

java文件編譯成class文件之後,必須要放到java虛擬機才能執行,類的整個生命週期如下
在這裏插入圖片描述
第一步我們是進行加載,加載是由類加載器進行加載的,也就是說把clss文件變成字節流,然後放到虛擬機的一個過程,其中方法區放的是類信息,靜態變量,常量,編譯後的代碼,同時在堆中生成一個代表該類的對象,作爲方法區訪問的入口

類加載器工作原理如下

    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

1、首先檢查這個類是否已經被加載,如果被加載過,返回該類的對象
2、如果沒有被加載過,並且如果父加載器不爲空,那麼調用父加載器的loadClass方法加載類,如果父加載器爲空,那麼調用虛擬機的加載器(bootstrap classLoader)來加載類。
3、如果還沒有成功的加載到類,那麼就調用自己的findClass(name)來加載類

其實就是通過遞歸調用查找頂層父類去加載,如果都加載不了,纔會交給自定義的類去加載,這就是雙親委派模式,也就是說有加載類請求的時候優先從父類加載,父類搜索不到該類的路徑時,纔會交由自定義的類加載器完成加載請求,這樣做的目的是爲了安全考慮,比如說用戶自定義一個java.util.hashmap,但是由於這個類已經由啓動類加載器加載了,這個時候自定義的這個路徑是不會再重新加載一次了

在這裏插入圖片描述

驗證階段主要就是驗證魔數,版本號,文件格式等
準備就是爲類變量分配內存並設置初始值,解析就是將符號引用替換爲直接引用的過程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章