类加载

  • 类加载子系统
  • 类加载器角色
  • 类加载过程
  • 加载
  • 链接
  • 初始化
  • 类加载器分类
  • 双亲委派机制
  • 如何打破双亲委派机制



JVM整体分为五大块:

  1. 类加载系统
  2. 运行时数据区
  3. 执行引擎
  4. 本地方法接口
  5. 垃圾回收

类加载子系统

Java基本的事件处理机制填空题 java事件处理机制的要点_双亲委派机制


     类加载器,通俗来讲就是从硬盘上加载由JDK编译后的字节码文件。classLoader 只负责 class 文件的加载,至于它是否可以运行,则由 Execution Engine 决定。 加载的类信息存放于一块称为方法区的内存空间。

类加载器角色

Java基本的事件处理机制填空题 java事件处理机制的要点_java_02

类加载过程

Java基本的事件处理机制填空题 java事件处理机制的要点_类加载_03

加载

     Class 只有在必须要使用的时候才会被装载, Java 虚拟机不会无条件地装载 Class 类型。Java 虚拟机规定, 一个类或接口在初次使用前, 必须要进行初始化。这里指的“使用”, 是指主动使用, 主动使用只有下列几种情况:

  1. 当创建一个类的实例时, 比如使用 new 关键字, 或者通过反射、克隆、反序列化。
  2. 当调用类的静态方法时, 即当使用了字节码 invokestatic 指令。
  3. 当使用类或接口的静态字段时(final 常量除外), 比如, 使用 getstatic 或者 putstatic 指令。
  4. 当使用 java.lang.reflect 包中的方法反射类的方法时。
  5. 当初始化子类时, 要求先初始化父类。
  6. 作为启动虚拟机, 含有 main 方法的那个类。

加载类处于类装载的第一个阶段。在加载类时, Java 虚拟机必须完成以下工作:

  1. 通过类的全名, 获取类的二进制数据流。
  2. 解析类的二进制数据流为方法区内的数据结构。
  3. 创建 java.lang.Class 类的实例, 表示该类型。

链接

     当类加载到系统后, 就开始连接操作, 验证是连接操作的第一步。它的目的是保证加载的字节码是合法、合理并符合规范的。

Java基本的事件处理机制填空题 java事件处理机制的要点_双亲委派机制_04

初始化

对类中静态成员进行赋值。
类什么时候初始化: new 对象, 使用类的静态成员, 反射动态加载类 Class.forName(), 子类被加载, 只访问了类中某个静态的常量

类加载器分类

站在 JVM 的角度看,类加载器可以分为两种:

  1. 启动类加载器(引导类加载器), 这部分不是用java语言写的
  2. 其他类加载器(这部分指的是用java语言写的类加载器)

站在 java 开发人员的角度来看,类加载器就应当划分得更细致一些.自 JDK1.2 以 来 java 一直保持者三层类加载器

  1. 启动类加载器,负责加载java核心类。
  2. 扩展类加载器 负责加载\jre\lib\ext目录下的类,包含应用程序类加载器。
  3. 应用程序类加载器,负责加载自己写的程序中的类。

Java基本的事件处理机制填空题 java事件处理机制的要点_java_05

双亲委派机制

Java基本的事件处理机制填空题 java事件处理机制的要点_JVM_06


     系统中的 ClassLoader 在协同工作时, 默认会使用双亲委托模式。即在类加载的时候, 系统会判断当前类是否己经被加载, 如果已经被加载, 就会直接返回可用的类, 否则就会尝试加载, 在尝试加载时, 会先请求双亲处理。通俗来讲就是:

  1. 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请 求委托给父类的加载器去执行。
  2. 如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终 将到达顶层的启动类加载器。
  3. 如果父类加载器可以完成类的加载任务,就成功返回,倘若父类加载器无法完 成加载任务,子加载器才会尝试自己去加载,这就是双亲委派机制。
    如果均加载失败,就会抛出 ClassNotFoundException 异常。

如何打破双亲委派机制