zoukankan      html  css  js  c++  java
  • JVM(三、双亲委派机制)

    javadoc的解释:

    ClassLoader的每一个实例都会有一个与之关联的父ClassLoader,当被要求去寻找一个类或者资源的时候,ClassLoader的实例就会对于类或者是资源的寻找委托给他的父ClassLoader(在他自己尝试找这个类或者资源之前),并层层向上委托。

    虚拟机内建的ClassLoader即Bootstrap根类加载器,他本身是没有双亲的,但是他可以作为一个类加载器的双亲。

    支持并发加载类的类加载器,被称为 parallel capable class loaders ,被要求在类的初始化期间调用ClassLoader.registerAsParallelCapable()将自身注册为parallelcapableclassloader。 ClassLoader默认是并发类加载器,但他的子类如果是并发的,还依然需要注册。

    当境委派模型并不是严格的层次委派模型时,要求类加载器必须是支持并行的类加载器,否则类加载就会导致死锁。因为加载器的锁(loader lock我也不知道咋翻译)在类的加载过程中一直不会释放。

    一般来说jvm虚拟机加载类来源于本地文件系统(与操作系统跟平台相关),但也可能来源于其他资源,比如网络,或者运行时的动态生成。

    在这种情况下,加载类的方法会把一个字节数组(调用 loadClassData() 返回byte[] ,通过defineClass(byte[])转为一个Class)转换为一个class对象,通过Class.newInstance 来创建对应对象。

    class NetworkClassLoader extends ClassLoader {
      String host;
      int port;

    public Class findClass(String name) {
      byte[] b = loadClassData(name);
      return defineClass(name, b, 0, b.length);
    }

    private byte[] loadClassData(String name) {
      // load the class data from the connection

    }
    }

    由类加载器创建的对象,其方法或者构造器可能引用了其他未加载的类,为了确定这些引用是什么(注意这些引用对应的类还未被装入,需要确定这些引用是什么) jvm虚拟机会调用加载这个类的class的classloader 来加载这些引用(再次跳入第一步 开始递归)

    1.获取ClassLoader

     1 public class MyTest06 {
     2 
     3     public static void main(String[] args) {
     4         String str = new String("212");
     5         C c = new C();
     6         System.out.println(str.getClass().getClassLoader());
     7         System.out.println(c.getClass().getClassLoader());
     8     }
     9 
    10 }
    11 class C{
    12     
    13 }//out: null
    sun.misc.Launcher$AppClassLoader@2a139a55

    第二个返回值说明自定义类C是由AppClassLoader 系统类加载器加载

    第一个返回值说明String由Bootstrap根加载器加载

    /** 如下是源码中对 getClassLoader() 方法的说明
         * Returns the class loader for the class.  Some implementations may use
         * null to represent the bootstrap class loader. This method will return
         * null in such implementations if this class was loaded by the bootstrap
         * class loader.
         * 如果类由bootstrap class loader加载 这个方法会返回null在一些jvm实现中
         * 
         * <p> If a security manager is present, and the caller's class loader is
         * not null and the caller's class loader is not the same as or an ancestor of
         * the class loader for the class whose class loader is requested, then
         * this method calls the security manager's {@code checkPermission}
         * method with a {@code RuntimePermission("getClassLoader")}
         * permission to ensure it's ok to access the class loader for the class.
         *
         * <p>If this object
         * represents a primitive type or void, null is returned.
         *
         * @return  the class loader that loaded the class or interface
         *          represented by this object.
         * @throws SecurityException
         *    if a security manager exists and its
         *    {@code checkPermission} method denies
         *    access to the class loader for the class.
         * @see java.lang.ClassLoader
         * @see SecurityManager#checkPermission
         * @see java.lang.RuntimePermission
         */    
    

    2.ClassLoader.loadClass()方法与Class.forName()方法

    class CL{
    	static {
    		System.out.println("class cl");
    	}
    }
    public class MyTest07 {
    
    	public static void main(String[] args) throws Exception {
    		ClassLoader clazzloader = ClassLoader.getSystemClassLoader();
    		Class<?> clazz = clazzloader.loadClass("jvm.CL");
    		System.out.println("==================================");
    		System.out.println(clazz);
    		System.out.println("==================================");
    		Class<?> clazz2 = Class.forName("jvm.CL");
    		System.out.println("==================================");
    		System.out.println(clazz2);
    	}
    
    }//out:
    ==================================
    class jvm.CL
    ==================================
    class cl
    ==================================
    class jvm.CL

    loadclass 只加载对应类,forName 会一并将类初始化

    不过调用 clazz.newInstance()会初始化该类:

    public class MyTest07 {
    
    	public static void main(String[] args) throws Exception {
    		ClassLoader clazzloader = ClassLoader.getSystemClassLoader();
    		Class<?> clazz = clazzloader.loadClass("jvm.CL");
    		System.out.println("==================================");
    		System.out.println(clazz);
    		System.out.println("==================================");
    		clazz.newInstance();
    		System.out.println("==================================");
    		Class<?> clazz2 = Class.forName("jvm.CL");
    		System.out.println("==================================");
    		System.out.println(clazz2);
    	}
    
    }out:
    ==================================
    class jvm.CL
    ==================================
    class cl
    ==================================
    ==================================
    class jvm.CL
    

      

    3.HotSpot实现中用null代替根加载器Bootstrap

    public class MyTest08 {
    
    	public static void main(String[] args) {
    		ClassLoader classloader = ClassLoader.getSystemClassLoader();
    		System.out.println(classloader);
    		while(classloader!=null) {
    			classloader= classloader.getParent();
    			System.out.println(classloader);
    		}
    	}
    
    }//out:
    sun.misc.Launcher$AppClassLoader@2a139a55
    sun.misc.Launcher$ExtClassLoader@7852e922
    null
    

    4.数组的classloader,数组是JVM在运行时动态生成的类型,没有类加载器,如果调用getClassLoader会返回对应元素的类加载器。

    public class MyTest09 {
    
    	public static void main(String[] args) {
    		String[] strs = new String[2];
    		System.out.println(strs.getClass().getClassLoader());
    		
    		System.out.println("============================");
    		
    		MyTest09[] ms = new MyTest09[2];
    		System.out.println(ms.getClass().getClassLoader());
    		
    		System.out.println("============================");
    		
    		int[] ints = new int[2];
    		System.out.println(ints.getClass().getClassLoader());
    	}
    
    }//out:
    null
    ============================
    sun.misc.Launcher$AppClassLoader@2a139a55
    ============================
    null
    

    其中String类型的类加载器是Bootstrap 在HotSpot实现中被表现为null

    源生类型则没有类加载器。

    5.类加载器一般都会伴随一个安全管理器,来确保类加载过程中是安全的

  • 相关阅读:
    基金定投是什么?定投的特点?
    Linux环境下MySQL 5.6安装与配置----亲测有效----纯离线安装
    OI生涯回忆录
    NOI2020游记
    Redis操作
    Redis概述
    Memcached
    动态规划——最长回文字符串
    两数之和&无重复字符最长字符串
    黑盒测试常见方法
  • 原文地址:https://www.cnblogs.com/chafanbusi/p/10644492.html
Copyright © 2011-2022 走看看