Java and java Official Website
I. java provides three ClassLoader classes:
1.BootStrap ClassLoader: It is called the start class loader and is the top class loader in the Java class loading hierarchy,Loads core class libraries in JDK, such as rt. jar, resources. jar, and charsets. jar.You can use the following program to obtain where the class Loader loads the relevant jar or class files:
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs(); for (int i = 0; i < urls.length; i++) { System.out.println(urls[i].toExternalForm()); }
Or
System.out.println(System.getProperty("sun.boot.class.path"));
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, which loads Java extension class libraries. By default, all the jar files under JAVA_HOME/jre/lib/ext/directory are loaded.
3.App ClassLoaderThe system class loader is used to load all jar and class files under the application classpath directory.
Ii. ClassLoader loading principle
1. Principles
ClassLoader usesParental delegated ModelTo search for classes. Each ClassLoader instance has a reference to the parent class loader (not an inheritance relationship, but a inclusion relationship), and the Bootstrap ClassLoader built in the VM) there is no parent class loader, but it can be used as the parent class loader for other ClassLoader instances. When a ClassLoader instance needs to load a class, it will first delegate this task to its parent class loader before trying to search for a class in person, this process is checked from top to bottom. First, the Bootstrap ClassLoader at the top of the class loader tries to load the data. If the data is not loaded, the task is transferred to the Extension ClassLoader for loading, if it is not loaded, it is forwarded to the App ClassLoader for loading. If it is not loaded, it is returned to the delegate initiator, this class is loaded into a specified file system or network URL. If none of them are loaded to this class, a ClassNotFoundException exception is thrown. Otherwise, a Class definition will be generated for the Class found, loaded into the memory, and the Class instance object in the memory will be returned.
2. Why do we need to use the parent-parent delegation model?
This avoids repeated loading. When the parent has already loaded the class, there is no need for the sub-ClassLoader to load it again. Considering the security, let's think about it. If we don't use this delegation mode, we can use custom strings to dynamically Replace the types defined in the core java APIs at any time, this poses a major security risk. The mode of parent-parent delegation can avoid this situation, because the String has been loaded by the bootstrap Class Loader (Bootstrcp ClassLoader) at startup, therefore, a custom ClassLoader can never load a self-Written String, unless you change the default algorithm of the ClassLoader Search Class in JDK.
3,
But how does the JVM determine that the two classes are the same during the search?
When determining whether two classes are the same, the JVM should not only judge whether the two classes are the same, but also whether they are loaded by the same classloader instance. JVM considers the two classes to be the same only when both of them are met. Even if two classes are of the same class bytecode, if they are loaded by two different ClassLoader instances, the JVM considers them to be two different classes.
4. ClassLoader architecture:
3. Custom ClassLoader: the custom ClassLoader must inherit java. lang. ClassLoader or URLClassLoader
Put two types of specific implementation code:
1. inherited from ClassLoader
Public class NetworkClassLoader extends ClassLoader {private String rootUrl; public NetworkClassLoader (String rootUrl) {this. rootUrl = rootUrl; }@ Override protected Class <?> FindClass (String name) throws ClassNotFoundException {Class clazz = null; // this. findLoadedClass (name); // The parent class has been loaded // if (clazz = null) {// check whether the class has been loaded byte [] classData = getClassData (name ); // obtain the bytecode array of the class file based on the binary name of the class. if (classData = null) {throw new ClassNotFoundException ();} clazz = defineClass (name, classData, 0, classData. length); // convert the byte code array of the class into an instance of the Class //} return clazz;} private byte [] GetClassData (String name) {InputStream is = null; try {String path = classNameToPath (name); URL url = new URL (path ); byte [] buff = new byte [1024*4]; int len =-1; is = url. openStream (); ByteArrayOutputStream baos = new ByteArrayOutputStream (); while (len = is. read (buff ))! =-1) {baos. write (buff, 0, len);} return baos. toByteArray ();} catch (Exception e) {e. printStackTrace ();} finally {if (is! = Null) {try {is. close ();} catch (IOException e) {e. printStackTrace () ;}}return null;} private String classNameToPath (String name) {return rootUrl + "/" + name. replace (". ","/") + ". class ";}}
2. inherited from URLClassLoader
Ublic class SimpleURLClassLoader extends URLClassLoader {// path of the Project class public static String projectClassPath = "E:/IDE/work_place/ZJob-Note/bin /"; // all test classes are in the same package. public static String packagePath = "testjvm/testclassloader/"; public SimpleURLClassLoader () {// set the ClassLoader loading path to super (getMyURLs ();} private static URL [] getMyURLs () {URL url = null; try {url = new File (projectClassPath ). toURI (). ToURL ();} catch (MalformedURLException e) {e. printStackTrace ();} return new URL [] {url};} public Class load (String name) throws Exception {return loadClass (name);} public Class <?> LoadClass (String name) throws ClassNotFoundException {return loadClass (name, false);}/*** rewrite loadClass without parental delegation ("java. "The Class at the beginning will still be loaded by the system's default ClassLoader) */@ Override public Class <?> LoadClass (String name, boolean resolve) throws ClassNotFoundException {Class clazz = null; // check whether class clazz = findLoadedClass (name) has been loaded in the cache of the HotSwapURLClassLoader instance; if (clazz! = Null) {if (resolve) {resolveClass (clazz) ;}return (clazz) ;}// if the class package name is "java. "Start, the system has the default loader AppClassLoader to load if (name. startsWith ("java. ") {try {// obtain the default system-loaded cl, that is, AppClassLoader ClassLoader system = ClassLoader. getSystemClassLoader (); clazz = system. loadClass (name); if (clazz! = Null) {if (resolve) resolveClass (clazz); return (clazz) ;}} catch (ClassNotFoundException e) {// Ignore }} return customLoad (name, this );} /*** custom loading ** @ param name * @ param cl * @ return * @ throws ClassNotFoundException */public Class customLoad (String name, ClassLoader cl) throws ClassNotFoundException {return customLoad (name, false, cl);}/*** custom loading * @ param name * @ param resolve * @ retur N * @ throws ClassNotFoundException */public Class customLoad (String name, boolean resolve, ClassLoader cl) throws ClassNotFoundException {// findClass () calls the findClass () of ClassLoader that is overloaded in URLClassLoader () method Class clazz = (SimpleURLClassLoader) cl ). findClass (name); if (resolve) (SimpleURLClassLoader) cl ). resolveClass (clazz); return clazz ;}@ Override protected Class <?> FindClass (String name) throws ClassNotFoundException {return super. findClass (name );}}
Iv. ClassLoader uninstall Class
The Class in JVM can be recycled by GC only when the following three conditions are met, that is, the Class is uninstalled (unload ):
- All instances of this type have been GC.
- The ClassLoader instance for loading this class has been GC.
- The java. lang. Class Object of this Class is not referenced anywhere.
We cannot control the timing of GC, so we cannot control the Class uninstallation.
Package testjvm. testclassloader; public class TestClassUnLoad {public static void main (String [] args) throws Exception {SimpleURLClassLoader loader = new SimpleURLClassLoader (); // use A custom loader to load A Class clazzA = loader. load ("testjvm. testclassloader. A "); Object a = clazzA. newInstance (); // clear reference a = null; // clear instance clazzA = null for this class; // clear reference loader = null for this class object; // clear ClassLoader reference of this class // execute a gc garbage collection System. gc (); System. out. println ("GC over ");}}
Reference:
Http://blog.csdn.net/xyang81/article/details/7292380
Https://my.oschina.net/xianggao/blog/367822