JVMの深い理解:クラスローダ

クラスローダ

JVM外部の行動に、このストリームのクラスによって、バイナリバイト完全修飾クラス名の記述を取得するクラスローディング・フェーズと呼ばれるこのアクション・コード・モジュールを達成するために実装され、「クラスローダ」を

任意のクラスのために、あなたはクラスローダと一緒にクラス自体によってロードされ、そのJVMの独自性を確立する必要があります。あなたはクラスローダの異なるタイプをロード言い換えれば、その後、JVM内の2つのクラスが異なっています。

三つのタイプのローダー

JVMは、Javaクラスローダによって他のBootstrapClassLoaderに加えて、三つの重要なクラスローダを構築し、すべてから継承を実装しますjava.lang.ClassLoader

  1. BootstrapClassLoader(ブートクラスローダー)  :C ++によって実現トップレベルクラスのローディングは、ローディングのために責任がある  %JAVA_HOME%/libJARパッケージおよびクラスまたはディレクトリ、または  -Xbootclasspathすべてのパラメータは、クラスパスで指定されました。
  2. ExtensionClassLoader(拡張クラスローダ)  :ディレクトリのロードを主に担当  %JRE_HOME%/lib/ext のjarパッケージとクラスディレクトリ、または  java.ext.dirs パスを指定したシステム変数の下のjarパッケージを。
  3. AppClassLoader(アプリケーションクラスローダ)  :ユーザーの皆様のためのアプリケーションのクラスパスに現在のすべてのjarパッケージおよびクラスをロードするための責任があるのローダ。

2つだけのJVMクラスローダーの観点から:

(1)ブートストラップクラスローダ:それは、C ++の実装のすべての権利、JVMの一部です。

(2)その他は、Java、すべての集積java.lang.ClassLoaderの抽象クラスによって実装されるクラスローダーの他の種類は、です。

第二に、親委譲モデル

クラスローダ

各クラスは、クラスローダことがあります。職場でのシステムClassLoderデフォルトの使用  親委任モデルを  。クラスがロードされたときである。つまり、システムが最初に現在のクラスがあまりにもロードされているかどうかを判断します。ロードされたクラスが直接返されますされている、またはロードしようとします。ロードされた場合、要求はまず親クラスローダに委譲されます  loadClass() ので、最終的にすべての要求は、ブートクラスローダのトップに転送する必要があり、プロセス  BootstrapClassLoader インチ 親クラスローダが処理できない場合は、自分自身だけで扱うことができます。親クラスローダがnullの場合は、ブートクラスローダを使用する  BootstrapClassLoader 親クラスローダとして。

注:クラスローダとの間に親子関係が継承的にではなく、組み合わせて(優先順位)

ソース

private final ClassLoader parent; 
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // 首先,检查请求的类是否已经被加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {//父加载器不为空,调用父加载器loadClass()方法处理
                        c = parent.loadClass(name, false);
                    } else {//父加载器为空,使用启动类加载器 BootstrapClassLoader 加载
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                   //抛出异常说明父类加载器无法完成加载请求
                }

                if (c == null) {
                    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;
        }
    }

あなたが親委任モデルを使用したくない場合は、次のカスタムクラスローダの必要性を、ClassLoaderクラスを統合するLOADCLASS()メソッド、必要性を書き換えます。

公開された134元の記事 ウォン称賛91 ビュー160 000 +

おすすめ

転載: blog.csdn.net/weixin_44588495/article/details/104130913