Javaの内部アーキテクチャを学び始めたばかりです。 jvm
の実行時に必要なクラスをロードし、クラスが見つからない場合にClassNotFoundException
がスローされ、特定のクラスローダーがクラスによって参照されるクラスをロードするクラスロードの概念を大まかに理解しました。
誰かがクラスローディングのフロー、つまりbootstrapサンプルのクラスローディングとユーザー定義のクラスローディングのシーケンスJava以下のコード。
import Java.io.File;
public class Sample
{
public static void main(String[] args)
{
String fileName = "sample";
File file = new File(fileName);
file.isFile();
}
}
また、参考資料から「classloader
がロードするクラスの名前空間を維持する」ことを学びました。名前空間とは、クラスのリテラル名を意味しますか?また、誰かがその意味/利点を説明できますか?
次のようにSample
クラスを実行します
> Java Sample
ちょっとした魔法のために、-verbose:class
オプションの出力をチェックアウトすると、たくさんの次の行が表示されます。
[Opened C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar]
.
.
.
.
.
.
[Loaded Java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Sample from file:/D:/tmp/]
[Loaded Java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar]
クラスがBootstrap
クラスローダー(またはPrimordial)によってロードされるかなり前に、\jre\lib\rt.jar
から多数のクラスがロードされます。これらは、任意のJavaプログラムを実行するための前提条件です。したがって、Bootstrapによってロードされます。
Jarの別のセットは、Extension
クラスローダーによってロードされます。この特定の例では、lib \jre\lib\ext
のクラスは必要ないため、ロードされません。ただし、拡張機能クラスローダーには、拡張機能ライブラリからクラスをロードするタスクが特に割り当てられています。
EDIT:標準プラットフォームとは別にJavaクラスSun/Oracleは、プラットフォームのコアAPIを拡張する。拡張機能libフォルダーに配置されたjarファイルは自動的にクラスパスに配置されるため、明示的にクラスパスに含める必要はありません。 素敵な公式記事 同じトピックについて。
最後に、クラスSample
は、BootstrapおよびExtensionのロードが完了した後、Application
クラスローダーによってロードされます。
新しいJVMが開始されるたびに、bootstrapクラスローダーは、_Javaクラス(Java.lang
パッケージ)およびその他のランタイムクラスを最初にメモリにロードします。 bootstrapクラスローダーは、他のすべてのクラスローダーの親です。そのため、親のない唯一のものです。
次は拡張機能クラスローダーです。親としてbootstrapクラスローダーを持ち、.jar
パスに保持されているすべてのJava.ext.dirs
ファイルからクラスをロードします。これらはJVMのクラスパスに関係なく使用できます。
開発者の観点から3番目に重要なクラスローダーは、システムクラスパスクラスローダーです。これは、拡張クラスローダーの直接の子です。 CLASSPATH
環境変数、Java.class.path
システムプロパティ、または-classpath
コマンドラインオプションで指定されたディレクトリおよびjarファイルからクラスをロードします。
ClassLoader名前空間
Javaでは、ClassLoader + Class
を使用してクラスが一意に識別されます。これは、2つの異なるクラスローダーによって同じクラスがロードされる可能性があるためです。
Class A loaded by ClassLoader A != Class A loaded by ClassLoader B
どのように役立ちますか?
クラスローダーごとに異なる保護およびアクセスポリシーを定義するのに役立ちます。別のクラスローダーを使用してロードされるアプレットの例を見てみましょう。サードパーティのアプリケーションがリソースにすべてアクセスすることは望ましくありません。したがって、セキュリティのために、異なる名前空間を維持することが重要です。
JVMは、クラスがロードされるpermgenエリアにランタイムプールを維持します。クラスが参照されるたびに、デフォルトのクラスローダーはクラスパスでクラスを見つけ、このプールにロードします。また、これはユーザー定義のクラスまたはJDKで提供されるクラスに固有のものではありません。クラスが参照されると、メモリにロードされます。
ClassLoaderによってロードされたクラスは、ClassLoaderインスタンスに内部的に保存されます
// The classes loaded by this class loader. The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private final Vector<Class<?>> classes = new Vector<>();
クラスをメモリに追加する必要がある場合、次の関数が呼び出されます。
// Invoked by the VM to record every loaded class with this loader.
void addClass(Class c) {
classes.addElement(c);
}
クラスローダーの動作に関する便利な図を見つけました。
Java仮想マシンは、bootstrapクラスを使用して、実装依存の方法で指定された初期クラスを作成することにより起動します。ローダー( §5.3.1 )。 Java仮想マシンは、初期クラスをリンクし、初期クラスとその中で宣言された静的インスタンス変数を初期化し、最後にpublicクラスメソッドvoid main(String [])。このメソッドの呼び出しは、それ以降のすべての実行を促進します。メインメソッドを構成するJava Virtual Machine命令を実行すると、追加のクラスとインターフェイスのリンク(およびその結果としての作成)、および追加のメソッドの呼び出しが発生する場合があります。
読み取り this リンク
ロードプロセスは、クラスローダーサブシステムとJVMのメモリ領域間の相互作用と見なすことができます。
クラスローダーは、3つの一般的な手順で機能します。1。)ロード2.)リンクおよび3.)初期化。
Classloader Subsystemとメモリ領域の間の非常に基本的な相互作用は、Linking中に発生します(他の相互作用とは別に!)
リンクアクティビティは、i。)検証ii。)準備とiii。)解決に細分されます。確認:セキュリティを強化するため、有効なコンパイルがチェックされます。ステップii。)準備-静的変数メモリが割り当てられ、デフォルト値が割り当てられます。そして
iii。)解決:シンボリック参照は、クラスレベルのデータと静的変数を含む「メソッド領域」からの元の参照に置き換えられます。