JVM加载问题,该如何聊?

JVM的由以下几部分组成:

  • 类加载器(ClassLoader): Java的动态类加载功能由ClassLoader子系统处理。它加载,链接。并在运行时(而非编译时)首次引用类时初始化类文件。
  • 运行时数据区(Runtime Data Area): Java虚拟机在执行Java程序的过程中会把它管理的内存分为若干个不同的数据区域。
  • 执行引擎(Execution Engine): 分配给运行时数据区的字节码将由执行引擎执行,执行引擎读取字节码并逐段执行。(字节码执行引擎编译成机器码后才可在物理机上执行)
  • 本地库接口(Native Interface): JNI将与本机方法库进行交互,并提供执行引擎所需的本机库
  • 本地库(Native Libraries): 本机库的集合,执行引擎执行时需要

Java代码执行流程:
-> java源程序通过编译器(javac.exe)对javac文件(.java)进行编译
–> 生成字节码文件(.class)
—> 类加载器把字节码加载到内存,放入运行时数据区的方法区内
-----> 执行引擎读取字节码并逐段执行
------> 解释执行(对字节码指令进行逐行的解释)编译执行(将热点代码编译成机器指令)
-------> 在操作系统(Windows,Linux等)上执行

简述java类加载机制?

Java中的所有类,都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中,并对数据进行校验,解析和初始化,最终形成可以被虚拟机直接使用的java类型。

Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是保证程序运行的基础类(像是基类)完全加载到jvm中,至于其他类,则在需要的时候才加载。

当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。如果没有意外,JVM将会连续完成3个步骤,所以有时也把这个3个步骤统称为类加载或类初始化。

加载:通过一个类的全限定名获取定义此类的二进制字节流,并将这个字节流所代表的静态存储结构转换成方法区中的运行时数据结构,并在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口,这个过程需要类加载器参与。

连接过程:验证-》准备-》解析
①验证(Verify):目的在于确保Class文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全,主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证
②准备(Prepare):为类变量分配内存并且设置该类变量的默认初始值,即零值
③解析:将常量池内的符号引用转换为直接引用的过程

初始化:对静态变量和静态代码块执行初始化工作

加载class文件的方式:
①从本地系统中直接加载
②通过网络获取,典型场景:Web Applet
③从zip压缩包中读取,成为日后jar、war格式的基础
④运行时计算生成,使用最多的是:动态代理技术

初始化阶段就是执行类构造器方法**<clinit>()** 的过程
此方法不需定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来(当代码中包含static变量时,<clinit>() 自动生成,如果没有静态代码快则不会生成)。
<clinit>()方法中的指令按语句在源文件中出现的顺序执行
<clinit>()不同于类的构造器。(关联:构造器是虚拟机视角下的<init>()
若该类具有父类,JVM会保证子类的<clinit>()执行前,父类的<clinit>()已经执行完毕
虚拟机必须保证一个类的<clinit>()方法在多线程下被同步加锁

类加载器的分类

类加载器:通过类的权限定名获取该类的二进制字节流的代码块。

JVM支持两种类型的类加载器 ,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)。

从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范却没有这么定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器,所以ExtClassLoader 和 AppClassLoader 都属于自定义加载器。

四者之间是包含关系,不是上层和下层,也不是子父类的继承关系:

  • 启动类加载器(Bootstrap ClassLoader):用来加载java核心类库,无法被java程序直接引用。
  • 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
  • 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它。
  • 用户自定义类加载器,通过继承 java.lang.ClassLoader类的方式实现。
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值