JVM-类加载器

135 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

JVM包含哪几部分

JVM 主要由四大部分组成:ClassLoader(类加载器),Runtime Data Area(运行时数据区,内存分区),Execution Engine(执行引擎),Native Interface(本地库接口)

  • ClassLoader:负责加载字节码文件即 class 文件,class 文件在文件开头有特定的文件标示,并且 ClassLoader 只负责class 文件的加载,至于它是否可以运行,则由 Execution Engine 决定。
  • Runtime Data Area:是存放数据的,分为五部分:Stack(虚拟机栈),Heap(堆),Method Area(方法区),PC Register(程序计数器),Native Method Stack(本地方法栈)。
  • Execution Engine:执行引擎,也叫 Interpreter。Class 文件被加载后,会把指令和数据信息放入内存中,Execution Engine 则负责把这些命令解释给操作系统,即将 JVM 指令集翻译为操作系统指令集。
  • Native Interface:负责调用本地接口的。

JVM重要的类加载器?

JVM 中内置了三个重要的 类加载器

  • BootstrapClassLoader(启动类加载器) :最顶层的加载类,由 C++实现,负责加载 JAVA_HOME/lib目录下的 jar 包和类或者被 -Xbootclasspath参数指定的路径中的所有类,并不继承自ClassLoader
  • ExtensionClassLoader(扩展类加载器) :主要负责加载 JRE_HOME/lib/ext 目录下的 jar 包和类,或被 java.ext.dirs 系统变量所指定的路径下的 jar 包。
  • AppClassLoader(应用程序类加载器) :程序中默认的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。

如何自定义类加载器?

  1. 继承ClassLoader父类
  2. 要遵从双亲委派机制,重写findClass方法
  • 注意不是重写loadClass方法,否则不会走双亲委派机制

双亲委派模型机制

即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类将直接返回,

加载的时候,首先会把该请求委派给父类加载器的 loadClass() 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader 中。当父类加载器无法处理时,向下尝试加载

双亲委派模型优点是什么:

  • 双亲委派模型避免了类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类
  • 保护核心API安全