JVM类加载器

JVM类加载器

JVM类加载器加载一个类分三个步骤:加载,连接,初始化,其中连接又包括验证,准备,解析三个部分。
JVM类加载器_第1张图片

加载

每个java文件生成为一个.class文件,也就是字节码文件,在加载这个阶段将.class文案读入内存,为为之创建一个jaav.lang.class对象

连接

  • 验证
    确保.class文件的字节流包含的信息是否符合虚拟机的要求
  • 准备
    为静态变量分配内存空间
  • 解析
    虚拟机将常量池中的符号引用替换为直接引用的过程

初始化

为类的静态变量赋予初始值

类加载器种类

虚拟机设计团队把机子动作放到了JVM外部实现,以便让应用程序决定如何获取所需的类。JVM提供了三种类加载器:

  • 启动类加载器(Bootstrap ClassLoader)
    又称为引导类加载器,负责加载JAVA_HOME\lib 目录中的一些核心类库,或通过-Xbootclasspath 参数指定路径中的,由C++编写,无法通过程序得到。
  • 扩展类加载器(Extension ClassLoader)
    负责加载 JAVA_HOME\lib\ext 目录中的,或通过 java.ext.dirs 系统变量指定路径中的类
    库,是启动类加载器的子类。
  • 应用程序类加载器(Application ClassLoader)
    负责加载用户路径(classpath)上的类库,通俗的讲也就是我们自己定义的那些类,是扩展类加载器的子类

JVM 通过双亲委派模型进行类的加载,当然我们也可以通过继承 java.lang.ClassLoader
实现自定义的类加载器

双亲委派

当一个类收到类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载器中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的class),子类加载器才会尝试自己去加载。
例如,我们需要加载一个我们自己定义的student类,它的类加载器是应用程序类加载器,那么应用程序类加载器会委托扩展类加载器进行加载,而扩展类加载器最终会委托启动类加载器帮我们进行加载,如果启动类加载器加载不了,在让扩展类加载器去加载,扩展类加载器加载不了,再让应用程序类加载器加载。

使用双亲委派的好处:保证了使用不同的类加载器最终得到的都是同样一个Object对象

注意:每一个类都有自己的一个类加载器,Student.class.getClassLoader()获得,可以通过Student.class.getClassLoader().getParent()获得父加载器类,也就是扩展类加载器,而启动类加载器,我们是无法直接获得的。

JVM类加载器_第2张图片

参考:https://blog.csdn.net/weixin_41751625/article/details/79357482

你可能感兴趣的:(java,jvm)