【Java学习之JVM】初识JVM

JVM(Java虚拟机)是Java程序运行的核心组件,也是Java语言广泛使用的原因之一。它能够将Java程序源代码编译成字节码文件并提供执行环境,同时具有跨平台、安全性高等优点。在本文中将简单描述JVM的一些内容,后续会分别进行详细的介绍。

JVM的组成部分

JVM由三个主要部分组成,分别是:类加载器、运行时数据区和执行引擎。

  1. 类加载器
    在Java程序中,类是一种重要的组织形式,而类加载器则是实现这种形式的重要工具。类加载器的主要任务是加载字节码文件到JVM中,并根据需要创建相应的Java类。JVM中的类加载器可以分为4种类型:
    • 引导类加载器(Bootstrap ClassLoader):负责加载Java类文件(如核心类库),是JVM内部自带的类加载器。
    • 扩展类加载器(Extension ClassLoader):负责加载JRE(Java Runtime Environment)扩展目录中的类。
    • 应用程序类加载器(Application ClassLoader):负责加载应用程序的自定义类。
    • 自定义类加载器(Custom ClassLoader):根据应用程序开发人员的需要,可以继承ClassLoader类,自定义类加载器方法。
  2. 运行时数据区
    JVM中的运行时数据区组织了Java程序运行时需要访问的数据。运行时数据区可以分为5部分:
    • 方法区(Method Area):保存所有已加载的类信息,如方法、字段和类的字节码等。
    • 堆(Heap):存放Java程序创建的对象实例,堆的大小是可以调整的,通常由JVM自动进行内存分配和垃圾回收。
    • 栈(Stack):保存函数和变量的运行信息。每个线程都有它自己的栈,栈中的数据都是私有的,只有当前线程可以访问。
    • 本地方法栈(Native Method Stack):保存调用本地方法时本地方法的堆栈信息,它和Java栈的作用是类似的。
    • 程序计数器(Program Counter):保存下一条要执行的指令的地址。
      JVM的任何操作都基于运行时数据区,包括类装载、内存分配、垃圾回收等。
  3. 执行引擎
    JVM中的执行引擎是负责执行Java字节码的核心组件。它可以将字节码转换为机器可以理解的指令,并且按照指令的顺序执行程序。
    JVM中的执行引擎包括两个组件:解释器和即时编译器。
    • 解释器:执行引擎中最基本的组件,它能够逐条地解释Java字节码并进行执行。在解释Java字节码时,解释器会将字节码翻译成对应的机器指令,然后让处理器执行这些指令。由于解释器需要逐条解释字节码,因此执行速度相对较慢,但是解释器可以在运行时进行优化,从而提高程序的执行效率。
    • 即时编译器:在运行时会将整个方法中的字节码全部编译成本地机器指令,从而提高程序的执行速度。在编译Java字节码时,即时编译器会根据代码的执行情况分别进行优化,并且在下次执行时利用优化结果。由于即时编译器需要编译整个方法,因此编译时间相对较长,但是编译后的代码执行速度很快,通常可以达到与C/C++等编译型语言相当的水平。

字节码执行

一旦类加载完成,JVM就可以对Java程序进行解释执行,即将Java字节码转化为机器可以理解的指令。解释执行通常是通过执行引擎(Execution Engine)来完成的。JVM支持两种不同的执行引擎:解释器和JIT编译器。

  1. 解释器(Interpreter):解释器逐条解释字节码,转换为机器指令执行,速度较慢。
  2. JIT编译器(Just-In-Time Compiler):JIT编译器可以将频繁调用的代码块编译为本地机器代码,从而提高程序运行速度。
    JVM中的执行引擎可以根据程序的实际情况动态地选择解释器或者即时编译器来执行Java代码,从而兼顾程序的执行速度和效率。

JVM的类加载子系统

  1. 加载(Loading):类加载器用于将字节码文件加载到JVM中,然后将类的信息存储在方法区中。
  2. 连接(Linking):连接过程可以分为验证、准备和解析三个阶段。
  • 验证(Verification):是类加载器链接阶段中的关键步骤之一。其主要作用就是确保所装载的.class文件中的字节码符合JVM规范,从而防止错误的字节码对虚拟机造成破坏。在完成验证后,虚拟机才会开始进行准备阶段工作。验证阶段主要检查以下内容:
    • 文件格式验证
    • 元数据验证
    • 字节码验证
    • 符号引用验证
  • 准备(Preparation):是类加载器链接阶段中的一个步骤,其主要作用是为初始化值为0的类静态变量分配内存空间,将类静态变量赋值为0,这就是需要重点关注的部分。
    • 当虚拟机加载一个类时,首先会为其分配一片所属线程的栈空间。
    • 每个栈帧(Stack Frame)包括局部变量表,每个局部变量槽(Local Variable Slot)可以存储一个int、float、long、double或引用类型值。
    • JVM在执行Java代码时,需要在堆(Heap)中动态分配内存来存储创建的对象。
    • 栈、堆和方法区(Method Area)都是JVM的内存区域,其中方法区存储了所有已装载的类型信息和常量池中的常量。
    • 当类被装载到内存中后,在链接阶段的准备阶段中,JVM会为每个类静态变量(static)分配所需的内存空间,并将默认的值(0 值)赋予该变量。
  • 解析(Resolution):是类加载阶段中三个步骤中最复杂的一个,也是相对较晚的处理步骤。解析过程是将虚拟机遇到的各种符号引用转换为真实的内存地址。由于Java中的方法调用和字段访问都是通过符号引用来实现的,因此必须在虚拟机执行时将其解析为真实内存地址,才能够顺利执行Java程序。
    Java程序中一般会出现如下几种类型的符号引用:
    • 类型引用:如java.lang.String
    • 字段引用:如java.lang.String.hashCode
    • 方法引用:如java.lang.String.toString()Ljava/lang/String
  1. 初始化(Initialization):类被初始化时,Java虚拟机会执行静态变量赋值和静态代码块中的代码,完成初始化工作。
  2. 使用
  3. 卸载

三、JVM的优缺点

JVM的最大优点是它可以使Java程序具有跨平台性,写一份Java代码不需要关心它最终会在哪个操作系统或架构上运行。同时,JVM的垃圾回收机制可以自动地管理内存,节省了程序员的时间和精力。此外,JVM的调试能力也非常强,可以按照代码的细节进行调试。

然而,JVM也存在一些缺点。基于JVM的程序相对于C/C++等原生语言开发的程序会有稍弱的性能表现,并且JVM的垃圾回收机制也可能导致一些性能问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值