JVMのClassLoader

4070 ワード

一、ClassLoaderとは何ですか.
 
“A class loader is an object that is responsible for loading classes”——java.lang.ClassLoader;
classLoaderはクラスローダの意味であり、クラス(.classファイルからjvmのclass)をjvmにロードする.
しかしclassLoaderもObjectで、どのようにjvmにロードされているのでしょうか.すべてのjavaクラスがclassLoaderによってロードされているのではないでしょうか.
したがって、クラスロードによってjvmをロードする必要がないclassLoaderがあるに違いありません.
jvmのbootstrap classloaderは、jvm実装の一部であるクラスローダです.
 
二、JVMにはどのようなClassLoaderがありますか?
 
classLoaderとは何か分かりましたが、classLoaderには何がありますか?
 
JVM自身がClassLoader--BootstrapClassLoaderを実現したと述べた.JVMと同様に、BootstrapClassLoaderはローカルコードで実装され、コアJavaClass(java.*の先頭にあるすべてのクラス)のロードを担当します.
また、jvmは2つのクラスローダ、ExtensionClassLoaderとSystemClassLoaderを提供しています.
彼らはjavaで書かれています.javaです.lang.ClassLoaderのサブクラスは、Bootstrap ClassLoaderによってロードされてから使用できます.
ここで、Extension ClassLoaderは拡張Javaclass(javax.*の先頭のクラスとJREのextディレクトリの下に格納されているクラスなど)のロードを担当し、System ClassLoaderはアプリケーション自体のクラスのロードを担当します.
もちろん、開発者自身もカスタムclassLoaderを実現することができます.
 
つまり、JVMに含まれるClassLoaderには、次のものがあります.
  • Bootstrap ClassLoaderは、コアJava Class(java.*の先頭クラスなど)
  • をロードする役割を果たします.
  • Extension ClassLoaderは、拡張Javaclass(変数-Djava.ext.dirsによって決定され、デフォルトはjdk 1.6.0_32/jre/lib/ext;/usr/java/packages/lib/ext)のロードを担当し、
  • System ClassLoaderは、アプリケーション自体のクラスのロードを担当します.

  • この3つのクラス・ローダにはparent関係がありますが、このparentは継承された関係ではなく、インスタンスが誰にロードされた関係を指します.System ClassLoaderのParentはExtension ClassLoaderであり、Extension ClassLoaderのParentはBootstrap ClassLoaderである.
     
     
    理論はいつも退屈で、やはり手を出して実現しましょう.コードを通じて彼らのparentを見て、以下のようにします.
     
    public static void main(String[] args) {
    	     System.out.println(ClassLoader.getSystemClassLoader().getParent());
    	     System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());
    }

    出力:
     sun.misc.Launcher$ExtClassLoader@42e816
     null

     
    ExtClassLoaderのparentはjavaクラスではないのでnullです.
     
    --------------------------------------------------------------------------------------
    補足:クラスローダに対応するjavaクラス
    bootstrap classloader------jvmのc++で書かれたdllクラスに対応
    Extenson ClassLoader------Launcher内部クラスExtClassLoaderに対応
    System ClassLoader------Launcher内部クラスAppClassLoaderに対応
    User Custom ClassLoader---任意のカスタムURLClassLoaderサブクラスに対応します(SecureClassLoaderまたはClassLoaderを直接継承することもできます)
    --------------------------------------------------------------------------------------
     
    三、ClassLoaderロードメカニズム
     
    classloaderロードクラスは両親の委託メカニズムを全面的に担当するために使用されている.
    すべての責任は、1つのClassをロードするとき、このClassが依存し、参照しているすべてのClassも、別のclassloaderを明示的に使用してロードしない限り、このclassloaderによってロードされます.
    両親の委託メカニズムはまずparentクラスのローダに探させ、parentが見つからない場合にのみ自分のクラスパスの中で探す.
    また、クラスロードにはcacheメカニズムが採用されており、cacheにこのClassが保存されている場合は直接返し、ファイルからClassを読み取り、変換しない場合はcacheに格納します.これは、Classを変更したが、JVMを再起動しなければ有効にならない理由です.
     
    四、ClassLoaderがclassをロードする過程
     
    classLoaderのロードメカニズムが分かれば、classをロードするプロセスも簡単に理解できます.以下のようにします.
    1)このClassがロードされたかどうかを検出します(つまりcacheにこのClassがあるかどうか)、8がある場合は2がない場合は
    2)parent classloaderが存在しない場合(parentがなければ、parentはbootstrap classloaderに違いない)、4
    3)parent classloaderロードを要求し、8に成功した場合、5に成功しなかった
    4)jvmにbootstrap classloaderからのロードを要求し、8に成功した場合
    5)Classファイルを探します(このclassloaderに関連するクラスパスから探します).見つからない場合は7.
    6)ファイルからClassを8に読み込む.
    7)ClassNotFoundExceptionを投げ出す.
    8)Classに戻る.
    このうち5.6ステップでは、ClassLoaderのfindClassメソッドを上書きすることで、独自のロードポリシーを実現できます.さらにloadClassメソッドを上書きして、独自のロードプロセスを実現します.
     
    五、カスタムClassLoader
     
    classloaderの原理とロードメカニズムが理解され、カスタムclassLoaderを実現することができます.
    カスタムclassLoaderを実現するには、カスタムclassPathを使用することが最も根本的な目的だと思います.実際には、このニーズを満たす方法がいくつかあります.例えば、
  • URLClassLoaderを生成するときにカスタムclassPathを指定し、実行時の動的ロードを実現することができる.
  • URLClassLoaderを継承することによってカスタムclassLoaderを実現し、URLClassLoaderのアドレスロジックを使用してカスタムClassPathをロードする.
  • ClassLoaderを継承することによってカスタムclassLoaderを実現し、カスタムclassPathアドレスとclassファイルの読み取りを実現することができる.

  • もちろん、カスタムclassLoaderを実現する方法は他にもありますが、重要なのは、ニーズに応じて適切なClassLoaderを実現することです.