JAVA系列之JVM加载

JVM的类加载

一.参考:

  1.  深入理解jvm笔记

  2. 类加载器

二.加载器简图

JAVA系列之JVM加载

加载过程中会先检查类是否被已加载,检查顺序是自底向上,从Custom ClassLoaderBootStrap ClassLoader逐层检查,只要某个classloader已加载就视为已加载此类,保证此类只所有ClassLoader加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。

2.1加载器:

1Bootstrap ClassLoader (引导类加载器)

    负责加载$JAVA_HOMEjre/lib/rt.jar里所有的classC++实现的核心库,也就是JVM调用每个系统的API实现系统功能,实现跨平台的主要模块,不是ClassLoader子类。开发者不能直接使用。

2Extension ClassLoader (扩展类加载器)

    负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOMEjre/lib/*.jar-Djava.ext.dirs指定目录下的jar,开发者可以直接使用。

3Application ClassLoader (应用加载)

    负责记载classpath中指定的jar包及目录中class。根据需要,通过class的全限定名来加载类,可以通过classLoader.getSystemClassLoader()来获取它。

4Custom ClassLoader (用户加载器)

    属于应用程序根据自身需要自定义的ClassLoader,继承java.lang.classLoader类。如tomcatjboss都会根据j2ee规范自行实现ClassLoader

    

    Tips:真正完成类的加载工作是通过调用 defineClass来实现的;而启动类的加载过程是通过调用 loadClass来实现的。前者称为一个类的定义加载器(defining loader),后者称为初始加载器(initiating loader)。 Java 虚拟机判断两个类是否相同的时候,使用的是类的定义加载器。也就是说,哪个类加载器启动类的加载过程并不重要,重要的是最终定义这个类的加载器。两种类加载器的关联之处在于:一个类的定义加载器是它引用的其它类的初始加载器。

      如类 com.example.Outer引用了类com.example.Inner,则由类 com.example.Outer的定义加载器负责启动类 com.example.Inner的加载过程。方法 loadClass()抛出的是 java.lang.ClassNotFoundException异常;方法 defineClass()抛出的是java.lang.NoClassDefFoundError异常

      类加载器在成功加载某个类之后,会把得到的 java.lang.Class(这里已经在heap区实例化)类的实例缓存起来下次再请求加载该类的时候,类加载器会直接使用缓存的类的实例,而不会尝试再次加载。也就是说,对于一个类加载器(每一个类都会有一个加载器)实例来说,相同全名的类只加载一次,即 loadClass方法不会被重复调用

加载:

1.    这里加载的意思是:每一个实例在new 其它的类时,就是一个classloader过程。

2.    这是一个动态过程

EgA实例需要实现使用B类的方法b1():

通过全限名在应用中查找.class文件--->读取文件到 method Area(解析一个*.class文件)--->classloader 实例化B一个在Heap区(分配内存),在当前的栈帧中通过B引用调用b1()--->在当前线程栈中添加一个新的栈帧,同时改变Program counter regsiters的值,指向新栈。(重复这个过程)

2.2详细的加载过程

JAVA系列之JVM加载




你可能感兴趣的:(jvm)