Java虚拟机JVM类加载机制(从类文件到虚拟机)

一、类加载机制简介

什么是类的加载

类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

类加载机制:所谓的类加载机制就是虚拟机将class文件加载到内存,并对数据进行验证,转换解析和初始化,形成虚拟机可以直接使用的java类型(即java.lang.class)

JVM的类加载机制分为五个部分:加载,验证,准备,解析,初始化,图示:

二、类加载机制过程

2.1、加载(Load)

所谓JVM加载过程,是查找和导入class文件,加载过程:

(1)通过类的全限定名获取这个类的二进制字节流;

(2)将字节流所代表的静态存储结构转换为方法区的运行时数据结构

(3)在JVM堆中生成代表这个类的java.lang.class对象(作为方法区中这些数据的访问入口)

2.2、连接(Linking)

2.2.1、验证(Verify)

JVM验证(Verify)这个过程是为了保证被加载类的正确性,保证其它后续步骤的正确正常执行,验证的过程包括:

  • 文件格式验证
  • 元数据验证
  • 字节码验证
  • 符号引用验证

2.2.2、准备(Prepare)

准备(Prepare)阶段,是为类变量分配内存并设置初始化值的。

eg:

public static int v = 9092;

注意:在类加载的准备(Prepare)阶段,v变量是赋值为0的而不是9092,这个值是在后续过程才赋值的

 private static int i;
public static void main(String[] args) {
    // 正常打印出0,静态变量在类加载的准备阶段会赋值0
    System.out.println(i);
}
public static void main(String[] args) {
   // 编译报错,因为局部变量没赋值不会自动生成初始化值
    int i;
    System.out.println(i);
}

2.2.3、解析(Resolve)

这个阶段是将常量池中的符号引用转换为直接引用的过程。所谓符号引用就是class文件中的:

1.  CONSTANT_Class_info
2.  CONSTANT_Field_info
3.  CONSTANT_Method_info
// 等等
...

直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。

直接引用和字符引用一个最明显的区别是,直接引用是目标是已经被加载到内存的,而字符引用并不一定已经加载到内存。

2.3、初始化(Initialize)

类加载的初始化阶段,是对类的变量和代码块执行初始化操作,是执行类构造器的过程,换句话说是对类的静态变量,静态代码块执行初始化操作

三、类加载器Classloader

3.1、类加载器简介

类的加载过程是在JVM之外的,目的是为了让应用程序决定如何获取需要的类。

类加载,也即类加载器通过类的全限定名获取其定义的二进制字节流,顾名思义,类加载器就是来加载class文件的。

3.2、类加载器分类

类加载器可以分为启动类加载器,拓展类加载器,应用程序类加载器

  • 1)、 Bootstrap classload(启动类加载器):负责加载$JAVA_HOMEjre/lib/rt.jar里所有的class或者--Xbootclasspath系统参数指定路径下的jar包。这个实现是由c++实现的
  • 2)、Extension Classload(拓展类加载器):负责加载java平台中拓展的一些jar,包括$JAVA_HOMEjre/lib/ext/*.jar或者-Djava.ext.dirs指定目录下的jar包
  • 3)、Application Classload(应用程序类加载器):负责加载classpath中指定的jar或者Djava.class.path指定路径的类和jar包
  • 4)、custom classload(自定义的类加载器):通过java.lang.ClassLoader的子类实现的类,属于程序根据需要自定义拓展的类加载器,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader

3.3、双亲委派

类的加载原则:按照“双亲委派”的原则加载的,当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此也即class类的加载,按照自顶向下的规则,由Bootstrap Classload到custom classload,就是由上层的加载类来加载类

目的:不管是哪个加载器加载这个类,最终都是委托给顶层的启动类加载器进行加载,保证了使用不同的类加载器最终得到的都是同样一个 Object 对象。

附录:参数资料

https://docs.oracle.com/javase/specs/jvms/se8/html/index.html

以上就是Java JVM类加载机制(从类文件到虚拟机)的详细内容,更多关于JVM类加载机制的资料请关注我们其它相关文章!

(0)

相关推荐

  • jvm之java类加载机制和类加载器(ClassLoader)的用法

    当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化. 一.类加载过程 1.加载 加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象,也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象. 类的加载由类加载器完成,类加载器通常由JVM提供,这些类加载器也是前面所有程序运行的基础

  • 从JVM分析Java的类的加载和卸载机制

    类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构. 加载.class文件的方式: 1.从本地系统中直接加载 2.通过网络下载.class文件 3.从zip,jar等归档文件中加载.class文件 4.从专有数据库中提取.class文件 5.将Java源文件动态编译为.class文件 类的加载的最终产品是位于堆区中的Class对象. Class对象封装了类在

  • 详解JAVA类加载机制(推荐)

    JAVA源码编译由三个过程组成: 1.源码编译机制. 2.类加载机制 3.类执行机制 我们这里主要介绍编译和类加载这两种机制. 一.源码编译 代码编译由JAVA源码编译器来完成.主要是将源码编译成字节码文件(class文件).字节码文件格式主要分为两部分:常量池和方法字节码. 二.类加载 类的生命周期是从被加载到虚拟机内存中开始,到卸载出内存结束.过程共有七个阶段,其中到初始化之前的都是属于类加载的部分 加载----验证----准备----解析-----初始化----使用-----卸载 系统可能

  • Java虚拟机JVM类加载机制(从类文件到虚拟机)

    一.类加载机制简介 什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载机制:所谓的类加载机制就是虚拟机将class文件加载到内存,并对数据进行验证,转换解析和初始化,形成虚拟机可以直接使用的jav

  • java虚拟机JVM类加载机制原理(面试必问)

    目录 1.类加载的过程. 1)加载 2)验证 3)准备 4)解析 5)初始化 2.Java 虚拟机中有哪些类加载器? 1)启动类加载器(Bootstrap ClassLoader): 2)扩展类加载器(Extension ClassLoader): 3)应用程序类加载器(Application ClassLoader): 3.什么是双亲委派模型? 4.为什么使用双亲委派模式? 5.有哪些场景破坏了双亲委派模型? 1)线程上下文类加载器 2)Tomcat 的多 Web 应用程序 3)OSGI 实现

  • 详解JVM类加载机制及类缓存问题的处理方法

    前言 大家应该都知道,当一个Java项目启动的时候,JVM会找到main方法,根据对象之间的调用来对class文件和所引用的jar包中的class文件进行加载(其步骤分为加载.验证.准备.解析.初始化.使用和卸载),方法区中开辟内存来存储类的运行时数据结构(包括静态变量.静态方法.常量池.类结构等),同时在堆中生成相应的Class对象指向方法区中对应的类运行时数据结构. 用最简单的一句话来概括,类加载的过程就是JVM根据所需的class文件的路径,通过IO流的方式来读取class字节码文件,并通

  • Java JVM类加载机制解读

    目录 1.什么是类加载 2.类加载的过程 2.1加载 2.2验证 2.3准备 2.4解析 2.5初始化[重中之重之重中重] 第一段代码: 第二段代码: 第三段代码: 最后一段代码: 总结 1.什么是类加载 首先你要知道一个类的从被加载到虚拟机内存中开始,到被初始化为止,是为类加载的整个过程.下图就是类加载的整个过程: 一个类只有经历了加载.验证.准备.解析.初始化这五个关卡才能被认为是实现了类加载.这,就是类加载. 注意一点:上面五个过程并不是按部就班地"完成",而是按部就班地&quo

  • JVM类加载机制原理及用法解析

    一.JVM 类加载机制 JVM 类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 1. 加载: 加载是类加载过程中的第一个阶段,这个阶段会在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的入口.注意这里不一定非得要从一个 Class 文件获取,这里既 可以从 ZIP 包中读取(比如从 jar 包和 war 包中读取),也可以在运行时计算生成(动态代理),也可以由其它文件生成(比如将 JSP 文件转换成对应的

  • 一文详解Java中的类加载机制

    目录 一.前言 二.类加载的时机 2.1 类加载过程 2.2 什么时候类初始化 2.3 被动引用不会初始化 三.类加载的过程 3.1 加载 3.2 验证 3.3 准备 3.4 解析 3.5 初始化 四.父类和子类初始化过程中的执行顺序 五.类加载器 5.1 类与类加载器 5.2 双亲委派模型 5.3 破坏双亲委派模型 六.Java模块化系统 一.前言 Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最 终形成可以被虚拟机直接使用的Java类型,这个过程

  • 详细分析JVM类加载机制

    目录 前言 1. jvm 的组成 2. 类加载 1. 加载 2. 链接 3. 初始化 3. 类加载器 引导类加载器(启动类加载器) 扩展类加载器 应用程序类加载器 4. 双亲委派机制 5. 类的主动/被动使用 结语 前言 ladies and gentleman , 你们好 ,我是羡羡 , 这节我们进入jvm的学习 , 我们知道 , jvm是java虚拟机, java代码的执行与 jvm 息息相关, 接下来我们来依次介绍 , 首先这节先来介绍 jvm 中的类加载部分 1. jvm 的组成 jvm

  • Android虚拟机与类加载机制详情

    目录 JVM与Dalvik 基于栈的虚拟机 字节码指令 执行过程 基于寄存器的虚拟机 寄存器 基于寄存器的虚拟机 ART与Dalvik dex2aot dexopt与dexaot Android N的运作方式 ClassLoader 介绍 ClassLoader加载流程与双亲委托机制 类加载 热修复 JVM与Dalvik Android应用程序运行在Dalvik/ART虚拟机,并且每一个应用程序对应有一个单独的Dalvik虚拟机实例.Dalvik虚拟机实则也算是一个Java虚拟机,只不过它执行的

  • 一篇文章弄懂JVM类加载机制过程以及原理

    目录 一.做一个小测试 二.类的初始化步骤: 三.看看你写对了没? 四.类的加载过程 五.类加载器的分类 1.启动类加载器(引导类加载器) 2.扩展类加载器 3.应用程序类加载器(系统类加载器) 六.类加载器子系统的作用 七.总结 一.做一个小测试 通过注释,标注出下面两个类中每个方法的执行顺序,并写出studentId的最终值. package com.nezha.javase; public class Person1 { private int personId; public Perso

  • Java通过自定义类加载器实现类隔离

    目录 前言 类隔离是什么 使用场景 解决方案 重写findClass 重写loadClass 总结 前言 由于微服务的快速迭代.持续集成等特性,越来越多的团队更倾向于它.但是也体现出了一些问题,比如在基础设施建设过程中,需要把通用功能下沉,把现有大而全的基础设施按领域拆分,考虑需要兼容现有生产服务,会产生不同的依赖版本,有时不注意就可以引发问题.比如本文遇到的依赖包版本冲突问题,以及如何利用类隔离技术解决的分析. 类隔离是什么 类隔离是一种通过类加载器实现加载所需类的实现方式,使得不同版本类间隔

随机推荐