JVM简介及面试题集锦一

JVM(Java Virtual Machine,Java虚拟机)是Java平台的核心组件之一,是一种能够在不同操作系统上运行Java程序的虚拟机。它的作用是将Java程序编译成字节码(bytecode),并在运行时将字节码解释成特定平台上的本地指令。

JVM由三部分组成:类加载器(Class Loader)、执行引擎(Execution Engine)和运行时数据区(Runtime Data Area)。

类加载器是JVM的一个重要组成部分,负责将Java字节码加载到内存中。JVM中存在三种类加载器:Bootstrap ClassLoader、Extension ClassLoader和Application ClassLoader。其中,Bootstrap ClassLoader是最顶层的类加载器,用于加载JVM自身的核心类;Extension ClassLoader用于加载Java的扩展库;Application ClassLoader则用于加载用户自己编写的Java类。

执行引擎是JVM的核心组件,它负责将Java字节码解释成特定平台上的本地指令。JVM的执行引擎有两种,一种是解释器,另一种是即时编译器(Just-In-Time Compiler,JIT)。解释器逐条解释Java字节码并执行对应的本地指令,而JIT会在程序执行过程中对热点代码进行动态编译,以提高程序的执行效率。

运行时数据区是JVM中存储数据的区域,它包括方法区、堆、栈和程序计数器等。其中,方法区用于存储类的结构信息、常量池等;堆用于存储Java对象实例;栈用于存储方法执行时的临时变量和方法调用信息;程序计数器用于记录当前线程执行的字节码指令位置。

JVM的出现,使得Java程序具有了跨平台的能力。Java程序只需要编译成字节码,就可以在不同的操作系统上运行,而不需要对每个平台都编写不同的代码。同时,JVM还提供了垃圾回收机制、线程管理等功能,使得Java程序开发更加高效和方便。

类加载器

VM的类加载机制是指,当Java程序启动时,JVM会按照特定的顺序加载类文件到内存中,以便程序可以使用这些类。JVM的类加载机制分为三个步骤:加载、链接和初始化。

  1. 加载:将.class文件加载到JVM中,生成对应的Class对象。

  2. 链接:将类与其他已经加载的类连接起来,包括验证、准备和解析三个阶段。

  • 验证:验证.class文件的格式是否正确,包括语法、字节码、符号引用等方面。
  • 准备:为类的静态变量分配内存并设置初始值(默认值)。
  • 解析:将符号引用转换为直接引用。
  1. 初始化:执行类的初始化代码,包括静态变量赋值、静态块等。

JVM的双亲委派模型是指,当一个类加载器(ClassLoader)需要加载一个类时,它会先委派给父类加载器去加载。如果父类加载器无法加载该类,那么再由自己的类加载器来加载。这种委派模型可以避免同一个类被重复加载,保证类的唯一性和一致性。

具体来说,当JVM需要加载一个类时,会按照以下的顺序进行类的搜索和加载:

  1. 首先,尝试使用启动类加载器(Bootstrap ClassLoader)加载类,它是JVM自身的一部分,用来加载JVM的核心类库,无法被Java程序直接引用。

  2. 如果启动类加载器无法加载该类,就尝试使用扩展类加载器(Extension ClassLoader)加载类,它用来加载Java扩展库中的类。

  3. 如果扩展类加载器也无法加载该类,就尝试使用应用程序类加载器(Application ClassLoader)加载类,它是Java程序默认的类加载器,用来加载Java应用程序中的类。

  4. 如果应用程序类加载器也无法加载该类,就尝试使用自定义的类加载器(Custom ClassLoader)加载类。自定义类加载器可以通过继承ClassLoader类并覆盖其中的方法来实现自己的加载逻辑。

总之,JVM的类加载机制和双亲委派模型保证了类的唯一性和一致性,并且提供了一种灵活的方式来扩展JVM的类加载功能。

执行引擎

JVM的执行引擎是Java程序的核心部分,它负责执行Java字节码并将其翻译为机器码。JVM的执行引擎包括两个主要的组件:解释器和即时编译器(JIT)。

  1. 解释器

解释器是JVM执行引擎的一个核心组件,它负责将Java字节码逐行翻译为机器码并执行。解释器可以实现跨平台性,因为它可以将Java字节码在任何平台上都翻译为相应的机器码。但是,解释器的执行效率比较低,因为它每次执行都需要将Java字节码翻译为机器码,这样会浪费大量的时间和计算资源。

  1. 即时编译器(JIT)

即时编译器是JVM执行引擎的另一个核心组件,它能够在运行时将Java字节码编译为本地机器码,从而提高程序的执行速度。JIT可以实现在程序运行过程中动态优化代码,将频繁执行的代码编译为本地机器码,提高程序的执行效率。在JIT出现之前,Java程序的执行效率很低,但是有了JIT之后,Java程序的执行速度可以与C++等编程语言相媲美。

JVM执行引擎的工作流程如下:

  1. 将Java源代码编译为Java字节码文件。

  2. JVM的类加载器将Java字节码文件加载到内存中。

  3. JVM的解释器将Java字节码翻译为机器码并执行。

  4. 如果解释器发现某段代码被频繁执行,就会将其编译为本地机器码并缓存起来。

  5. JVM的即时编译器会在运行时将Java字节码编译为本地机器码,从而提高程序的执行速度。

总之,JVM的执行引擎是Java程序的核心部分,它实现了Java程序的跨平台性和动态优化能力,提高了程序的执行效率和性能。

运行时数据区

JVM运行时数据区是JVM在运行Java程序时使用的内存区域,它包括了以下几个部分:

  1. 程序计数器(Program Counter Register)

程序计数器是一块较小的内存区域,它用来记录JVM正在执行的字节码指令的地址。在任何时候,程序计数器都只会保存一个线程的指令地址,因此,它可以用来实现线程切换、恢复执行等操作。

  1. 虚拟机栈(JVM Stack)

虚拟机栈是Java方法执行的内存模型,它用来存储局部变量、方法参数、中间计算结果等数据。每个线程都有一个独立的虚拟机栈,它的生命周期与线程相同。当一个方法被调用时,就会在虚拟机栈中创建一个栈帧,用来存储该方法的局部变量、参数等信息,当方法执行完毕时,对应的栈帧也会被弹出栈。

  1. 堆(Heap)

堆是JVM运行时数据区中最大的一块内存区域,用来存储Java程序中创建的对象实例。堆是所有线程共享的,它在JVM启动时被分配,大小可以通过JVM参数进行设置。

  1. 方法区(Method Area)

方法区是用来存储类的相关信息,如类的定义、方法信息、常量池等。方法区也是所有线程共享的,它在JVM启动时被分配,大小可以通过JVM参数进行设置。

  1. 运行时常量池(Runtime Constant Pool)

运行时常量池是方法区的一部分,它用来存储编译期生成的字面量和符号引用,以及运行期生成的字符串常量等数据。运行时常量池是每个类或接口的独立部分,在类加载时被创建。

  1. 本地方法栈(Native Method Stack)

本地方法栈与虚拟机栈的作用类似,不同之处在于它用来存储Java程序调用本地方法(Native Method)时使用的数据。

JVM运行时数据区的各个部分之间有着密切的联系和协作关系,它们共同构成了JVM的内存管理体系。JVM在运行Java程序时,会根据程序的需要动态分配和回收内存,保证程序能够正常执行。在实际的Java应用程序中,JVM运行时数据区的内存大小和分配策略可以通过JVM参数进行调整,以适应不同的应用场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值