当前位置: 首页 > news >正文

Java虚拟机:JVM介绍

1024 程序员节日快乐!愿您我的代码永远没有 bug ,人生永远没有 bug !

在这里插入图片描述

JVM

  • 概述
  • JVM 架构

在这里插入图片描述

概述

JVM( Java Virtual Machine ,Java 虚拟机),是 Java 语言的运行环境,是运行所有 Java 程序的抽象计算机(一个虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现)。JVM 的主要功能是执行 Java 字节码,JVM 是 Java 程序的中间表示形式,是 Java 程序从源代码到实际运行的中间桥梁。Java 编译器将 Java 源代码编译成字节码后,JVM 将这些字节码解释或编译成特定平台上的机器指令并执行,而无需针对每个平台重新编写和编译源代码。

JVM 具有一套完整的硬件架构,包括处理器、堆栈、寄存器等,以及相应的指令系统。这使得 JVM 能够模拟实际计算机的各种功能,从而在不同的操作系统和硬件平台上实现 Java 程序的运行。这种特性使得 Java 语言具有跨平台性。

JVM 还负责管理 Java 程序的内存,包括堆内存和栈内存的分配、回收和释放。其使用垃圾回收机制来自动管理内存,从而减轻了开发者的负担。此外,JVM 还支持多线程并发执行,可以创建和管理多个线程,实现并发编程。同时,还提供了安全管理机制,对 Java 程序的访问权限进行控制,保护系统的安全性。

在实际开发中,JVM 的应用广泛,如 Tomcat 、Jetty 等 Web 服务器都使用 JVM 来运行 Java Web 应用程序。同时,JVM 的特性和机制也在许多常用功能和程序实现中发挥着基础作用。

JVM 架构

在这里插入图片描述

一、类加载子系统

负责在运行时动态加载 Java 类。其主要功能是将类的 .class 文件中的二进制数据读入到内存中,并将其放置在运行时数据区的方法区内。然后在堆区创建一个 java.lang.Class 对象,用来封装类在方法区内的数据结构。这个 Class 对象就是类加载的最终产品,其向 Java 程序员提供了访问方法区内的数据结构的接口。

类加载的过程包括加载、验证、准备、解析和初始化五个阶段。加载阶段主要是将类的二进制数据读入内存;验证阶段确保 .class 文件的正确性和安全性;准备阶段为类的静态变量分配内存并设置初始值;解析阶段主要处理符号引用到直接引用的转换;初始化阶段主要是执行类构造器 < clinit >() 方法的过程。

在类加载的过程中,类加载器起到了关键的作用。类加载器负责查找和加载类的二进制数据。在 JVM 中,有多种类加载器,它们之间通常存在包含关系,遵循双亲委派机制(即一个类加载器在加载类时,会首先委托其父类加载器去加载,只有在父类加载器无法加载该类时,才会自己尝试加载)。

二、运行时数据区(内存模型)

负责为程序运行时提供必要的数据存储和操作空间,确保程序能够正确、高效地执行。JVM 在执行 Java 程序时划分的多个不同的数据区域,这些区域各自有着特定的功能与作用。同时,这些区域共同协作,为 Java 程序的执行提供了必要的内存环境。JVM 通过内存管理和垃圾回收机制来确保这些区域的有效利用和安全性。

  • 方法区( Method Area ):这是一个线程共享的区域,用于存储类信息、常量、静态变量等数据。在 JDK 8 之前,方法区也被称为永久代( PermGen ),而在 JDK 8 及以后版本中,元数据区( Metaspace )取代了永久代
  • 堆( Heap ):这是 JVM 中最大的一块内存区域,主要功能是存放 Java 对象实例和数组。堆区是线程共享的,所有的对象实例以及数组都要在堆上分配。堆内存还可以按照垃圾分代收集的角度划分为年轻代和老年代,年轻代又进一步细分为 Eden 区、From Survivor 区和 To Survivor 区
  • 虚拟机栈( Virtual Machine Stack ):每个线程在创建时都会创建一个虚拟机栈,用于存储方法的局部变量和部分结果。虚拟机栈由一个个栈帧组成,每个栈帧对应着一次方法调用
  • 程序计算器( Program Counter Register ):这是一个线程私有的内存区域,用于存储当前线程正在执行的 Java 方法的指令地址。由于 Java 是支持多线程的语言,每个线程需要有独立的程序计数器来记录当前线程执行的位置
  • 本地地方栈( Native Method Stack ):用于支持 native 方法的执行。与虚拟机栈类似,但是为 native 方法服务的

三、执行引擎

负责将编译后的字节码解释成可执行的机器指令,从而实现了 Java 程序的运行。其主要功能是将 Java 字节码转换为特定平台上的本地机器指令,以便操作系统能够识别和执行。

执行引擎主要包括解释执行和即时编译两种方式。解释执行是 JVM 启动时根据语法规范对字节码逐行解释执行,将每行字节码文件的内容翻译成本地平台的机器指令。这种方式性能较低,但具有跨平台的优势。而即时编译是可以将频繁执行的代码优化为本地机器码,提高执行效率。

在执行过程中,执行引擎从程序计算器中获取要执行的指令索引,使用指令索引从操作数栈中获取要执行的指令,然后将指令转换为具体的机器指令交给操作系统执行。执行引擎的输入是二进制流,处理过程是将字节码转换为机器指令的过程,输出的是执行结果。

四、本地方法接口

其主要用于实现 Java 代码与本地( Native )代码(如 C 、C++ 代码)之间的交互。本地方法接口允许 Java 程序调用本地方法,从而实现与底层本地代码的交互。这些本地方法在 Java 虚拟机中不会有实现,而是在本地代码中实现。

本地方法接口提供了一系列函数,用于 Java 代码和本地代码之间的数据传递、对象操作、异常处理等。常用的 JNI 函数包括获取类、方法和字段的 ID ,如 FindClass() 、GetMethodID() 、GetFieldID() 等;调用 Java 方法,如 CallVoidMethod() 、CallObjectMethod() 、CallStaticVoidMethod() 等;以及访问和操作 Java 对象,如 NewObject() 、GetObjectField() 、SetObjectField() 等。

本地方法接口在 Java 平台上实现了 Java 与本地代码之间的桥梁,极大地扩展了 Java 的应用范围。JVM 通过调用本地方法栈上的本地方法来执行本地接口的功能。本地接口的作用是融合不同的编程语言为 Java 所用,其初衷是融合 C 或 C++ 程序。在 Java 诞生的时候,为了立足并调用 C 或 C++ 的程序,Java 在内存中开辟了一块区域专门用于处理标记为 native 的代码。具体做法是在本地方法栈中登记 native 方法,在执行引擎执行时加载 native libaries 。

五、本地方法库

本地方法库,指那些包含本地方法实现的库文件。这些本地方法通常是用 C 、C++ 或其他底层语言编写的,并通过本地方法接口(如 JNI 、Java Native Interface )与 Java 代码进行交互。

本地方法库的存在主要是为了扩展 Java 的功能,使其能够调用底层系统函数、访问硬件资源或与其他语言编写的库进行交互。通过本地方法库,Java 程序可以执行一些 Java 本身无法直接完成的操作,从而提高了程序的灵活性和性能。

在 Java 程序中调用本地方法库中的函数时,需要使用本地方法接口。这个接口提供了一组函数,用于在 Java 代码和本地代码之间进行数据传递、对象操作以及异常处理等。通过本地方法接口,Java 程序可以安全地调用本地方法库中的函数,并处理相关的数据交换和异常情况。

需要注意的是,本地方法库的使用需要谨慎处理,以确保程序的稳定性和安全性。由于本地代码直接运行在底层系统上,因此可能存在一些安全风险,如内存泄漏、非法访问等。因此,在编写和使用本地方法时,需要遵循一定的编程规范和最佳实践,以确保程序的正确性和安全性。

总的来说,JVM 架构为 Java 程序的运行提供了强大的支持和保障,使得 Java 程序能够在不同的操作系统和硬件平台上实现跨平台运行。同时,JVM 的调优和性能优化也是确保 Java 程序高效稳定运行的关键。通过优化 JVM 的内存使用、延迟和吞吐量等指标,可以提高程序的性能和响应速度,从而提升用户体验和系统的整体性能。

http://www.lryc.cn/news/467453.html

相关文章:

  • R数据科学 16.5.3练习题
  • 通过conda install -c nvidia cuda=“11.3.0“ 安装低版本的cuda,但是却安装了高版本的12.4.0
  • 简易CPU设计入门:验证取指令模块
  • 【MySQL数据库】MySQL主从复制
  • CDC变更数据捕捉技术是什么?和ETL有什么不同?
  • 一种用于推进欧洲临床中心中风管理的联邦学习平台即服务
  • 给哔哩哔哩bilibili电脑版做个手机遥控器
  • opencv dnn模块 示例(27) 目标检测 object_detection 之 yolov11
  • 鸿蒙开发融云demo初始化和登录
  • 手机防窥膜的工作原理是怎样的?有必要使用防窥膜吗?
  • 【Python_PySide6学习笔记(三十九)】基于QLineEdit实现自定义文本框,用于格式化文本,每四个字符后添加一个空格
  • 23种设计模式口诀速记
  • n > m 将输出文件 m 和 n 合并。 n < m 将输入文件 m 和 n 合并。 有什么区别
  • 语言障碍在自闭症儿童中的表现及应对
  • (成功解决)ubuntu22.04不小心更新成了atzlinux12.7.1,右上角出现红色错误符号
  • 005 C#语言基本元素概览,初识类型,变量与方法
  • Spring Cloud --- Sentinel 授权规则
  • 计算机网络基础 - 传输层(1)
  • Chrome DevTools:Console Performance 汇总篇
  • 【Spark | Spark-Core篇】RDD行动算子action
  • 23.Redis核心数据结构
  • 免费送源码:Node.JS+Express+MySQL Express 流浪动物救助系统 计算机毕业设计原创定制
  • 基于Java+Springboot+Vue开发的旅游景区管理系统
  • Python 实现的风控系统(使用了kafka、Faust、模拟drools、redis、分布式数据库)
  • Linux运维_Rocky8 安装配置Zabbix
  • jQuery Mobile 滚屏事件
  • 3.1.1ReactOS系统中搜索给定长度的空间地址区间函数的实现
  • arm64系统不支持32位的解决armel armhf
  • 【毕业设计】工具大礼包之『Maven3.6.3安装与配置』
  • gin入门教程(9):路由分组与路由版本控制