面试造飞机系列-JVM

JVM类加载机制

2020-06-12  本文已影响0人  Chermack

一、类加载子系统概述

二、类加载的三个阶段

1、加载阶段

  1. 通过一个类的全限定名获取定义此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

字节码文件的来源可以是

2、链接阶段(颜色越深越重要)。

链接阶段

3、初始化阶段。

初始化阶段

例如有下面一段代码:

package com.ronghao.loadclass;

public class ClinitTest {
    //任何一个类声明以后,都会至少有一个构造器
    private int a = 1;
    private static int c = 3;
    public static void main(String[] args) {
        int b = 2;
    }
    public ClinitTest(){
        a= 10;
        int d= 20;
    }
}

编译为class文件后用jclasslib打开,可以看到字节码文件的方法中有一个Clinit,里面的字节码程序就是用于初始化上述代码的静态变量c。


初始化阶段-执行类构造器方法<Clinit>

三、类加载器的分类

JVM支持两种类型的类加载器。

1、引导类加载器(Bootstrap ClassLoader)

2、自定义类加载器(User-Defined ClassLoader)

自定义类加载器是通过Java语言实现的,全都是抽象类ClassLoader的子类。
Java中内置的已经定义好的自定义类类加载器最常见的是两个,即ExtClassLoader和AppClassLoader,它们都是定义在sun.misc包下的Launcher类中的静态内部类

ClassLoader的继承关系

扩展类加载器(Extension ClassLoader)-

系统类加载器(应用程序类加载器,AppClassLoader)

四、获取类加载器的几种方式。

获取类加载器的几种方式
    /**
     * output:
     * null
     * sun.misc.Launcher$AppClassLoader@18b4aac2
     * sun.misc.Launcher$ExtClassLoader@1b6d3586
     */
    public static void main(String[] args) {
        try {
            //1.String类是Bootstrap加载器加载的,是C++实现,所以为null。
            ClassLoader classLoader = Class.forName("java.lang.String").getClassLoader();
            System.out.println(classLoader);
            //2.当前程序的上下文类加载器为应用程序加载器。
            ClassLoader classLoader1 = Thread.currentThread().getContextClassLoader();
            System.out.println(classLoader1);
            //3.系统类加载器(应用程序类加载器AppClassLoader)的父加载器是
            System.out.println(ClassLoader.getSystemClassLoader().getParent());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

五、主动使用与被动使用

Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象。
Java程序对类的使用方式为:主动使用和被动使用
主动使用分为以下7中情况:

六、双亲委派机制

工作原理:

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


    双亲委派机制
上一篇 下一篇

猜你喜欢

热点阅读