java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > jvm运行原理及类加载器

jvm运行原理以及类加载器实例详解

作者:silly8543

这篇文章主要给大家介绍了关于jvm运行原理以及类加载器的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

JVM运行原理

首先从“.java”代码文件,编译成“.class”字节码文件,然后类加载器将“.class”字节码文件中的类给加载带JVM中,最后就是JVM执行写好的代码。执行过程如下图

类加载器

类加载过程

加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载

加载

一旦JVM进程启动之后,一定会先把类加载到内存中,然后从main()方法的入口代码开始执行

public class HelloWorld {
    public static void main(String[] args) {
        
    }
}

加载指是将类CLass文件读入到内存中,并创建一个java.lang.Class对象

类的加载器由类加载器完成,类加载器通常由JVM提供,除此之外,可以通过继承ClassLoader基类来创建自己的类加载器

通过使用不同的类加载器,可以从不同来源加载类的二进制数据

准备阶段

验证

根据Java虚拟机规范,来校验加载进来的“.class”文件中的内容,是否符合指定的规范,如果“.class”文件被人篡改,里面的字节码不符合规范,那么JVM是没法执行这个字节码。所在把“.class”文件加载到内存后,必须先验证一下,检验他必须完全符合JVM规范,才交给JVM来运行。其主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证

准备

给引用的类分配一定的内存空间,然后给里面的类变量(也就是static修饰的变量)分配内存空间,来一个默认的初始值

解析

实际上是把将类的二进制数据中的符号引用替换成直接引用的过程,这个部分的内容比较复杂,设计到JVM的底层

解析主要包括:

初始化

初始化是为类的静态变量赋予正确的初始值,准备阶段和初始化阶段看似有点矛盾,其实是不矛盾的,如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说),到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10

一个非常重要的规则,就是如果初始化一个类的时候,发现他的父类还没初始化,那么必须先初始化他的父类

加载器

启动类/根类加载器

Bootstrap ClassLoader,他主要是负责加载我们在机器上安装的Java目录下的核心类的,是用原生代码来实现的,并不继承自 java.lang.ClassLoader(负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作

扩展类加载器

Extension ClassLoader,负责加载JRE的扩展目录,lib/ext或者由java.ext.dirs系统属性指定的目录中的JAR包的类。由Java语言实现,父类加载器为null

应用程序类加载器

Application ClassLoader,被称为应用(也称为系统)类加载器,它负责在JVM启动时加载来自Java命令的-classpath选项、java.class.path系统属性,或者CLASSPATH换将变量所指定的JAR包和类路径。程序可以通过ClassLoader的静态方法getSystemClassLoader()来获取系统类加载器。如果没有特别指定,则用户自定义的类加载器都以此类加载器作为父加载器。由Java语言实现,父类加载器为ExtClassLoader。

类加载器加载Class大致要经过如下8个步骤:

  1. 检测此Class是否载入过,即在缓冲区中是否有此Class,如果有直接进入第8步,否则进入第2步
  2. 如果没有父类加载器,则要么Parent是根类加载器,要么本身就是根类加载器,则跳到第4步,如果父类加载器存在,则进入第3步
  3. 请求使用父类加载器去载入目标类,如果载入成功则跳至第8步,否则接着执行第5步
  4. 请求使用根类加载器去载入目标类,如果载入成功则跳至第8步,否则跳至第7步
  5. 当前类加载器尝试寻找Class文件,如果找到则执行第6步,如果找不到则执行第7步
  6. 从文件中载入Class,成功后跳至第8步
  7. 抛出ClassNotFountException异常
  8. 返回对应的java.lang.Class对象

自定义类加载器

除了上面那几种之外,还可以自定义类加载器,去根据你自己的需求加载你的类

类加载机制

JVM的类加载机制主要有如下3种:

双亲委派机制

这就是所谓的**双亲委派模型:**先找父亲去加载,不行的话再由儿子来加载

总结

到此这篇关于jvm运行原理以及类加载器的文章就介绍到这了,更多相关jvm运行原理及类加载器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文