回転:jvm classloader
5735 ワード
回転:jvm classloader
作者:白菜发表时间:September 7,2010分类:JAVA
1.簡単な実験から始めます.
(1)Eclipseの下に簡単なJava projectを建てて、簡単なプログラムを書いて、以下のようにします:
package com.javaeye.loader;public class URLClassLoaderTest { public void show() { System.out.println("I am running..."); }}
(2)プロジェクト対応bin/com/javaeye/loaderの下にURLClassLoaderTestを見つける.classファイル、このファイルを保存し、プロジェクト全体を削除します.
(3)ディスクのどこにでもフォルダcomを作成し、comにjavaeyeを作成し、javaeyeにloaderを作成し、私はCディスクjavaディレクトリの下に構築し、作成が完了したら(2)に保存するURLClassLoaderTest.classファイルをコピーし、(4)非ローカルApacheサーバ上の任意の場所にフォルダcomを作成し、comにjavaeyeを作成し、javaeyeにloaderフォルダを作成し、完了後(2)に保存するURLClassLoaderTest.classファイルはその中にコピーして、私の非ローカルコンピュータIPは192.168.66.250で、システムはLinux Redhatで、創立が完成した後に私達はアクセスして(5)両端のテストコードを与えることができます:
@Test public void testInWeb() throws Exception{ URL[] urls = new URL[]{new URL("http://192.168.66.250/root/java/")}; URLClassLoader loader = new URLClassLoader(urls); Class clas = loader.loadClass("com.javaeye.loader.URLClassLoaderTest"); Method m = clas.getMethods()[0]; Object o = clas.newInstance(); m.invoke(o); } @Test public void testInFileSystem() throws Exception{ URL[] urls = new URL[]{new URL("file:/C:/java/")}; URLClassLoader loader = new URLClassLoader(urls); Class clas = loader.loadClass("com.javaeye.loader.URLClassLoaderTest"); Method m = clas.getMethods()[0]; Object o = clas.newInstance(); m.invoke(o); }
両端のコードをそれぞれ実行し、出力結果は次のとおりです.
Javaコード
I am running...
分析:
なぜ上記の運転結果が現れるのかは明らかにcomのためである.learn.loader.URLClassLoaderTestオブジェクトはメモリにロードされ、このオブジェクトのshowメソッドが実行される.
考え:
Java言語は、Java仮想マシン(JVM)上で実行されるため、Javaでコンパイルされているプログラムがプラットフォームから独立した特殊なフォーマットであり、実行されているマシンに依存しないため、異なります.このフォーマットは、従来の実行可能プログラムフォーマットとは大きく異なる.CまたはC++で作成されたプログラムとは異なり、Javaプログラムは実行可能なファイルではなく、多くの独立したクラスファイルから構成され、各ファイルはJavaクラスに対応しています.また、これらのクラスファイルは、すぐにすべてメモリにロードされるのではなく、プログラムの必要に応じてメモリにロードされます.ClassLoaderは、JVMでクラスをメモリにロードするツールです.
2.jvm classLoader architecture
同じ例のコードを示します.
public void testClassLoader2() throws Exception{ URL[] urls = new URL[]{new URL("http://192.168.66.250/root/java/")}; URLClassLoader loader = new URLClassLoader(urls); System.out.println(loader.getClass()); System.out.println(loader.getParent().getClass()); System.out.println(loader.getParent().getParent().getClass()); System.out.println(loader.getParent().getParent().getParent()); }
実行結果は次のとおりです.
Javaコード
class java.net.URLClassLoaderclass sun.misc.Launcher$AppClassLoaderclass sun.misc.Launcher$ExtClassLoadernull
この実行結果を説明するには、jvm classloader構造を以下の図に示す必要があります.
図に示すように、javaセキュリティ砂箱モデルの最上位レベルのクラスローダセキュリティメカニズムを実現するために、javaはデフォルトで「親委任ロードチェーン」構造を採用しており、図では4層に分かれている.私たちの上の運行結果と一つ一つ対応しています.
最下層:User Custom ClassLoader/ユーザカスタムクラスローダ(java.lang.ClassLoaderのサブクラス)は、プログラムの実行中にjavaを通過する.lang.ClassLoaderのサブクラスはclassファイルを動的にロードし、javaの動的リアルタイムクラス読み込み特性を体現する.明らかにjavanet.URLClassLoaderはこの層に属する.
AppClassLoader層:System ClassLoader/システムクラスローダ、主にjava-classpath/-Djavaを担当する.class.pathが指すディレクトリの下のクラスとjarパッケージは作業中です.java.lang.ClassLoader.getSystemClassLoader()は、上記sunを得ることができる.misc.Launcher$AppClassLoaderはこのレイヤに属します.
ExtClassloaderレイヤ:Extension ClassLoader/拡張クラスローダ、主にjdk_を担当home/lib/extディレクトリのjarパッケージまたは-Djava.ext.dirs指定ディレクトリのjarパッケージ作業、sun.misc.Launcher$ExtClassLoaderはこの層に属する.
最上位:Bootstrap ClassLoader/起動クラスローダ、主にjdk_を担当home/libディレクトリのコアapiまたは-Xbootclasspathオプションで指定したjarパッケージワークは、なぜこのレイヤの出力がnullに対応するのですか?BootstrapはC++で書かれているので、Javaでは見えませんnullです.次から:http://www.javaeye.com/topic/753834