One, Java provides three kinds of ClassLoader to load class:
1.BootStrap ClassLoader: called the Startup class loader, is the topmost class loader in the Java class loading hierarchy, responsible for loading the core class libraries in the JDK, such as: Rt.jar, Resources.jar , Charsets.jar, etc. , can be obtained by the following program where the loader loaded the relevant jar or class file:
url[] URLs = sun.misc.Launcher.getBootstrapClassPath (). Geturls (); for (int i = 0; i < urls.length; i++) { System.out.println (Urls[i].toexternalform ()); }
Or
The final result is:
/java/jdk1.6.0_22/jre/lib/resources.jar
/java/jdk1.6.0_22/jre/lib/rt.jar
/java/jdk1.6.0_22/jre/lib/sunrsasign.jar
/java/jdk1.6.0_22/jre/lib/jsse.jar
/java/jdk1.6.0_22/jre/lib/jce.jar
/java/jdk1.6.0_22/jre/lib/charsets.jar
/java/jdk1.6.0_22/jre/classes/
2.Extension ClassLoader: called the Extension class loader, is responsible for loading the Java Extension Class library, loading all the jars in the java_home/jre/lib/ext/by default.
3.app ClassLoader: Called the system ClassLoader, is responsible for loading all the jar and class files in the application Classpath directory.
Second, the loading principle of ClassLoader
1. Introduction of principle
ClassLoader uses a parent- delegate model to search for classes, and each ClassLoader instance has a reference to the ClassLoader (not an inherited relationship, a contained relationship), and the virtual machine's built-in ClassLoader (Bootstrap ClassLoader) itself does not have a parent classloader, but can be used as a parent ClassLoader for other ClassLoader instances. When a ClassLoader instance needs to load a class, it attempts to search for a class by itself, delegating the task to its parent classloader, which is checked from top to bottom, first by the topmost class loader bootstrap classloader trying to load, If not loaded, the task is forwarded to the extension ClassLoader attempt to load, if not loaded, then to the app ClassLoader to load, if it is not loaded, then return to the initiator of the delegate, It loads the class into a URL such as a specified file system or network. If none of them are loaded into this class, the ClassNotFoundException exception is thrown. Otherwise, the found class generates a class definition, loads it into memory, and finally returns the class instance object in memory.
2. Why use parents to entrust this model?
Because this avoids repeated loading, there is no need for the child classloader to load again when the parent has loaded the class. Considering the security factors, let's imagine that if we don't use this delegate pattern, we can use a custom string at any time to dynamically replace the type defined in the Java Core API, so there's a very big security risk, and the way that parents delegate, you can avoid this situation, Because the string has been loaded by the Boot class loader (BOOTSTRCP ClassLoader) at startup, the user-defined ClassLoader can never load a string that he writes, Unless you change the default algorithm for the ClassLoader search class in the JDK.
3,
but the JVM in the search class, and how to determine the two class is the same?
The JVM determines whether the two classes are the same, not only to determine whether the two class names are the same, but also to determine whether the same class loader instance is loaded. The JVM considers the two classes to be the same only if the two are both satisfied. even if the two class is the same class bytecode, if it is loaded by two different ClassLoader instances, the JVM will consider them to be two different classes.
4, ClassLoader system structure:
Third, custom ClassLoader, custom ClassLoader need to inherit Java.lang.ClassLoader or inherit URLClassLoader
Put two types of specific implementation code:
1. Inherit from ClassLoader
Public classNetworkclassloaderextendsClassLoader {PrivateString Rooturl; PublicNetworkclassloader (String rooturl) { This. Rooturl =Rooturl; } @OverrideprotectedClass<?> Findclass (String name)throwsclassnotfoundexception {Class clazz=NULL;//This.findloadedclass (name);//The parent class is loaded//if (clazz = = null) {//Check if the class has been loaded byte[] Classdata = Getclassdata (name);//gets the byte-code array of the class file, based on the binary name of the if(Classdata = =NULL) { Throw Newclassnotfoundexception (); } clazz= DefineClass (name, Classdata, 0, classdata.length);//converts a class's byte-code array to an instance of class//} returnClazz; } Private byte[] Getclassdata (String name) {InputStream is=NULL; Try{String path=Classnametopath (name); URL URL=NewURL (path); byte[] Buff =New byte[1024*4]; intLen =-1; is=Url.openstream (); Bytearrayoutputstream BAOs=NewBytearrayoutputstream (); while(len = is.read (buff))! =-1) {baos.write (buff,0, Len); } returnBaos.tobytearray (); } Catch(Exception e) {e.printstacktrace (); } finally { if(Is! =NULL) { Try{is.close (); } Catch(IOException e) {e.printstacktrace (); } } } return NULL; } Privatestring Classnametopath (string name) {returnRooturl + "/" + Name.replace (".", "/") + ". Class"; } }
2. Inherit from URLClassLoader
UblicclassSimpleurlclassloaderextendsURLClassLoader {//the path where the project class is located Public StaticString Projectclasspath = "e:/ide/work_place/zjob-note/bin/"; //all of the tested classes are under the same package Public StaticString PackagePath = "testjvm/testclassloader/"; PublicSimpleurlclassloader () {//set the path to ClassLoader loading Super(Getmyurls ()); } Private Staticurl[] Getmyurls () {URL URL=NULL; Try{URL=NewFile (Projectclasspath). Touri (). Tourl (); } Catch(malformedurlexception e) {e.printstacktrace (); } return Newurl[] {URL}; } PublicClass load (String name)throwsexception{returnloadclass (name); } PublicClass<?> loadclass (String name)throwsClassNotFoundException {returnLoadClass (Name,false); } /*** Rewrite loadclass, do not use parental delegation mechanism ("java.") The first class will still be loaded by the system default ClassLoader)*/@Override PublicClass<?> loadclass (String name,BooleanResolvethrowsclassnotfoundexception {Class clazz=NULL; //See if the class has been loaded under the Hotswapurlclassloader instance cacheClazz =Findloadedclass (name); if(Clazz! =NULL ) { if(Resolve) {resolveclass (clazz); } return(Clazz); } //if the package name of the class is "java." Start, there is the system default loader Appclassloader loaded if(Name.startswith ("java."))) { Try { //get the system default load cl, i.e. AppclassloaderClassLoader system =Classloader.getsystemclassloader (); Clazz=System.loadclass (name); if(Clazz! =NULL) { if(Resolve) Resolveclass (clazz); return(Clazz); } } Catch(ClassNotFoundException e) {//Ignore } } returnCustomload (Name, This); } /*** Custom Loading *@paramname *@paramCL *@return * @throwsclassnotfoundexception*/ PublicClass customload (String name,classloader cl)throwsClassNotFoundException {returnCustomload (Name,false, CL); } /*** Custom Loading *@paramname *@paramResolve *@return * @throwsclassnotfoundexception*/ PublicClass customload (String name,BooleanResolve,classloader cl)throwsClassNotFoundException {//Findclass () calls the Findclass () method that overloads the ClassLoader inside URLClassLoaderClass Clazz =((Simpleurlclassloader) cl). Findclass (name); if( Resolve) ((Simpleurlclassloader) cl). Resolveclass (Clazz); returnClazz; } @OverrideprotectedClass<?> Findclass (String name)throwsClassNotFoundException {return Super. Findclass (name); }}
Iv. ClassLoader Unloading class
The class in the JVM can be reclaimed by GC only if the following three conditions are met, that is, the class is unloaded (unload):
- All instances of this class have been GC.
- The ClassLoader instance that loads the class has already been GC.
- The Java.lang.Class object for this class is not referenced anywhere.
The timing of the GC is not controllable, so the same is true of our unloading of class.
PackageTestjvm.testclassloader; Public classTestclassunload { Public Static voidMain (string[] args)throwsException {simpleurlclassloader loader=NewSimpleurlclassloader (); //load A with a custom loaderClass Clazza = loader.load ("Testjvm.testclassloader.a"); Object a=clazza.newinstance (); //Clear related referencesA =NULL;//clear instances of this classClazza =NULL;//clears the reference to the class objectLoader =NULL;//clear ClassLoader references to this class//perform a GC garbage collectionSystem.GC (); System.out.println ("GC over"); }}
Reference Documentation:
http://blog.csdn.net/xyang81/article/details/7292380
https://my.oschina.net/xianggao/blog/367822
Java--classloader Create, load class, unload class