亲宝软件园·资讯

展开

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

silly8543 人气:0
想了解jvm运行原理以及类加载器实例详解的相关内容吗,silly8543在本文为您仔细讲解jvm运行原理及类加载器的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:jvm运行原理详解,jvm类加载器详解,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种:

双亲委派机制

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

总结

加载全部内容

相关教程
猜你喜欢
用户评论