JVM--类加载相关

365 阅读2分钟

先上图:

1626263245006.png

类加载器ClassLoader:

classLoader作为一个运输工具存在,将本地硬盘/网络class文件以流的形式加载到JVM的方法区中,形成DNA元数据模板--即方法区(JDK8.0的元数据区)。

注意点:字符串常量池和静态变量存放在堆中,这个可以查看JVM--方法区文档。

类加载器种类:

引导类加载器(BootstapClassLoader):C语言编写吗,加载核心库

1626266723941.png

扩展类加载器(ExtClassLoader):加载扩展目录下的类库

1626266828404.png

系统类加载器(SystemClassLoader):应用的类一般都有此加载器加载。

1626266883059.png

自定义加载器:作为一个扩展的存在。

1626266950098.png

类加载器之间的关系:不是上下级的父子关系,而是包含关系,比如ExtClassLoader包含BootstapClasLoader对象。

为什么要这个处理加载器?这牵扯到了双亲委派机制。

双亲委派机制:起保护作用,防止java核心库类被覆盖

Java虚拟机对class文件是按需加载的方式,采用的就是双亲委派模式,即把请求交由父类处理,是一种任务委派模式。

工作原理:

先一直向上委托直到引导类加载器,若上方加载器无法加载,则向下交由子加载器尝试加载,一旦加载到类就成功返回。

1626267335092.png

双亲委派机制的优势:

避免类的重复加载

保护程序安全,防止核心API被随意篡改。

加载的三个步骤:

1、Loading(加载)

1626263957290.png

生成的Class对象,是保存在堆中的,它也是个对象,通过它能关联上方法区中的所有信息,这也是反射的原理。Class类中有个ForName(String className),能通过路径获取到相应的Class对象,再通过Class对象获取生成对象或获取相应对象的属性,方法等等。

1626264021679.png

2、Linking(链接)

  • 验证:校验字节码文件是否合法。
  • 准备:为类变量(除final static 修改的变量外)分配空间,并给出默认值。
  • 解析:将符号引用转为直接引用。

1626264982193.png

3、Initialization(初始化)

类构造器方法(clinit)--这个是编译时自动生成的方法(存放静态变量和静态代码块,执行时按源文件中出现的顺序执行)

类的构造器方法(init)--就是我们常说的构造方法,是虚拟机视角下的定义。

1626266006304.png

这有个非法的前向引用,没弄懂,有清楚的朋友能留个言吗?多谢多谢!

类的其他说明:

同类的判断:完整类名+classLoader

1626268037824.png

类的主动加载和被动加载:

区别:被动加载不会执行初始化步骤 1626268336709.png