首頁  >  問答  >  主體

java程序运行的时候,是把所有的class文件都加载到内存吗?还是用的什么加载什么?

一运行就全部加载?

高洛峰高洛峰2744 天前541

全部回覆(4)我來回復

  • PHP中文网

    PHP中文网2017-04-18 10:51:58

    並不是全部加載,可以理解為按需加載。
    例如繼承的父類,實現的接口,聲明的變量,方法的返回類型等。

    就是在使用目前的類別時,缺少哪些必要的類別都會立即載入。

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:51:58

    按需加載。
    類別載入的時機:

    1)遇到new、getstatic、putstatic或invokestatic這4條字節碼指令時,如果類別沒有進行過初始化,則需要先觸發其初始化。產生這4個指令的最常見的Java程式碼場景是:使用new關鍵字實例化物件的時候、讀取或設定一個類別的靜態欄位(被final修飾、已在編譯期間將結果放入常數池的靜態字段除外)的時候,以及呼叫一個類別的靜態方法的時候。
    2)使用java.lang.reflect套件的方法對類別進行反射呼叫的時候,如果類別沒有進行過初始化,則需要先觸發其初始化。
    3)當初始化一個類別的時候,如果發現其父類別還沒有進行過初始化,則需要先觸發其父類別的初始化。
    4)當虛擬機器啟動時,使用者需要指定一個要執行的主類別(包含main()方法的那個類別),虛擬機會先初始化這個主類別。
    5)當使用JDK 1.7的動態語言支援時,如果一個java.lang.invoke.MethodHandle實例最後的解析結果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,並且這個方法句柄所對應的類別沒有進行過初始化,則需要先觸發其初始化。
    對於這5種會觸發類別進行初始化的場景,虛擬機器規範中使用了一個很強烈的限定語:“有且只有”,這5種場景中的行為稱為對一個類別進行主動引用。除此之外,所有引用類別的方式都不會觸發初始化,稱為被動引用。

    來源:深入理解JVM 7.2 類別載入的時機

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-18 10:51:58

    這一塊還沒深入了解,不敢誤人子弟。
    我知道的,虛擬機器在運作的時候,會預先載入一個常用的class,像是java.lang套件下面的。
    至於你在程式中自己引用的class檔案/jar套件之類的,是有一個載入過程的。
    當虛擬機器需要一個class文件,他會呼叫預設的classLoader.loadClass()去加載,這個方法首先在已經加載的class中查找,找得到當然返回,找不到則交給父加載器。層層查找沒有之後,classLoader會呼叫findClass方法去檔案中載入。
    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;
        }

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:51:58

    http://blog.csdn.net/briblue/...
    可以參考這篇部落格 講的不錯

    回覆
    0
  • 取消回覆