图解JVM-1. JVM与Java体系结构

一、前言

在 Java 开发的广袤天地里,不少开发者都遭遇过令人头疼的状况。线上系统毫无征兆地卡死,陷入无法访问的僵局,甚至直接触发 OOM(OutOfMemoryError,内存溢出错误);面对 JVM 的 GC(Garbage Collection,垃圾回收)难题,满心困惑却不知从何下手;新项目上线时,面对纷繁复杂的 JVM 参数设置,只能无奈采用默认值,结果可能导致性能不佳。在面试中,背诵 JVM 原理概念容易,但被问及实际项目中的 JVM 参数调优、GC 和 OOM 问题解决策略时,却常常一脸茫然。

这种现象背后,反映出大部分 Java 开发人员的知识短板。很多人热衷于钻研 SSM、微服务等上层技术,却忽视了 Java 技术的核心 ——Java 虚拟机。实际上,核心类库的 API 如同数学公式,而 JVM 知识则是公式的推导过程。只有深入理解 JVM,才能在开发中如鱼得水,游刃有余地应对各种复杂问题。掌握 JVM 知识,不仅是应对面试的 “利器”,更是中高级程序员的必备技能,能够满足项目管理与调优的需求,还能让开发者在追求极客精神的道路上更进一步。

二、Java 及 JVM 简介

(一)Java 语言的发展历程与地位

回顾 Java 的发展轨迹,1990 年,Sun 计算机公司的 Green Team 在 Patrick Naughton、Mike Sheridan 及 James Gosling 的带领下,开发出最初名为 oak 的语言,后更名为 Java。1995 年,Java 和 HotJava 产品正式发布,Java 自此登上历史舞台。随后,JDK(Java Development Kit,Java 开发工具包)不断迭代更新,从 1996 年的 JDK 1.0,到 2019 年的 JDK 12,每一次版本升级都带来新的特性与改进。在 TIOBE 语言热度排行榜上,Java 长期名列前茅,这充分彰显了其在软件开发领域的重要地位。

(二)JVM:跨语言的强大平台

JVM 作为 Java 平台的关键支柱,具有卓越的跨语言特性。它不仅支持 Java 语言,Groovy、Scala、JRuby、Kotlin 等语言也能在 JVM 上运行。这是因为 JVM 只关注字节码文件,只要其他编程语言的编译结果符合 JVM 的内部指令集、符号表及辅助信息要求,就能被 JVM 识别并运行。不同编译器可以生成相同的字节码文件,且这些字节码文件具备跨 JVM 运行的能力。

随着 Java 7 的发布,JVM 通过 JSR - 292 规范,进一步拓展了对非 Java 语言编写程序的支持。以多语言混合编程为例,在一个项目中,并行处理可以用 Clojure 语言,展示层使用 JRuby/Rails,中间层采用 Java,各层语言交互顺畅,就像使用原生 API 一样便捷,这都得益于 JVM。围绕 JSR - 292 的一系列项目和功能改进,推动着 JVM 从 “Java 语言的虚拟机” 向 “多语言虚拟机” 转变。

三、虚拟机与 Java 虚拟机

(一)虚拟机的分类与特点

虚拟机(Virtual Machine)本质上是一款软件,用于执行虚拟计算机指令,可分为系统虚拟机和程序虚拟机。像 Virtual Box、VMware 这类系统虚拟机,是对物理计算机的全面仿真,能提供运行完整操作系统的软件平台。而程序虚拟机的典型代表便是 Java 虚拟机,它专为执行单个计算机程序而设计,执行的是 Java 字节码指令。无论是哪种虚拟机,在其上面运行的软件都受限于虚拟机提供的资源。

(二)Java 虚拟机的独特魅力

Java 虚拟机是执行 Java 字节码的虚拟计算机,拥有独立运行机制,其运行的字节码不一定由 Java 语言编译而来。JVM 平台的众多语言共享着它的跨平台性、出色的垃圾回收器以及可靠的即时编译器。Java 技术的核心就在于 JVM,所有 Java 程序都在 JVM 内部运行。

JVM 的主要作用是为二进制字节码提供运行环境,负责将字节码装载到内部,并解释或编译成对应平台的机器指令执行。每一条 Java 指令在 JVM 规范中都有详尽定义。同时,JVM 具有 “一次编译,到处运行”、自动内存管理和自动垃圾回收等显著特点。并且,JVM 运行在操作系统之上,与硬件没有直接交互,这也是其实现跨平台的关键所在。

四、JVM 的整体结构

HotSpot VM 是当下高性能虚拟机的杰出代表,采用解释器与即时编译器并存的架构。在这种架构下,解释器可以快速启动,对代码进行解释执行;而即时编译器则会在运行过程中,将热点代码编译成本地机器码,大大提高执行效率。正是得益于这种架构,Java 程序的运行性能今非昔比,足以与 C/C++ 程序相媲美。

五、Java 代码执行流程

Java 代码的执行是一个严谨且有序的过程。首先,Java 源文件(.java)通过 Java 编译器编译成字节码文件(.class)。字节码文件包含了 JVM 指令集、符号表以及其他辅助信息。接着,JVM 启动时,类加载器会将字节码文件加载到内存中。在运行时,解释器逐行解释执行字节码指令,如果遇到热点代码(频繁执行的代码),即时编译器会介入,将其编译成机器码,直接在底层硬件上高效运行。这个过程中,JVM 的内存管理系统负责分配和回收内存,垃圾回收器会自动清理不再使用的对象,确保内存的高效利用。

六、JVM 的架构模型

Java 编译器输入的指令流主要基于栈式指令集架构,与之相对的是基于寄存器的指令集架构。

基于栈式架构具有诸多优势:设计和实现相对简单,适合资源受限的系统;它避开了寄存器分配的难题,采用零地址指令方式分配;指令流中的指令大多是零地址指令,执行过程依赖操作栈,指令集较小,编译器容易实现;并且无需特定硬件支持,可移植性强,便于实现跨平台。不过,其缺点也较为明显,性能相对较低,实现相同功能往往需要更多指令。

基于寄存器架构则以 x86 二进制指令集为典型代表,像传统 PC 以及 Android 的 Davlik 虚拟机都采用这种架构。它的性能优秀,执行效率高,完成一项操作所需的指令更少。但它严重依赖硬件,可移植性较差。

以 2 + 3 的计算操作为例,基于栈的计算流程中,需要先将操作数压入栈,再进行计算,最后从栈中取出结果;而基于寄存器的计算流程则直接在寄存器中进行操作,效率更高。由于 Java 追求跨平台性,不同平台 CPU 架构差异大,所以选择了基于栈的架构。尽管如今嵌入式平台已不是 Java 程序的主流运行环境,但考虑到庞大的 Java 生态和兼容性,暂时不会更换为基于寄存器的架构。

七、JVM 的生命周期

(一)虚拟机的启动

Java 虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个初始类由虚拟机的具体实现指定。引导类加载器负责加载 JVM 运行所需的核心类库,为后续的程序执行奠定基础。

(二)虚拟机的执行

当一个 Java 程序开始执行时,实际上是启动了一个 Java 虚拟机进程。在程序执行期间,JVM 持续运行,负责执行字节码指令、管理内存、进行垃圾回收等操作。只有当程序正常执行结束、遇到异常或错误异常终止、因操作系统错误导致进程终止,或者调用 Runtime 类或 System 类的 exit 方法、Runtime 类的 halt 方法(且 Java 安全管理器允许这些操作)时,JVM 才会停止运行。此外,JNI(Java Native Interface)规范中描述了使用 JNI Invocation API 加载或卸载 JVM 时的退出情况。

(三)虚拟机的退出

JVM 的退出情况较为多样。程序正常结束,自然会触发 JVM 退出;程序执行过程中若遭遇未处理的异常或错误,导致程序无法继续运行,JVM 也会异常终止;操作系统出现错误,影响到 JVM 进程时,JVM 同样会被迫终止。另外,通过代码主动调用特定方法,如 Runtime.getRuntime ().exit (0),也能使 JVM 退出。在 JNI 编程中,使用 JNI Invocation API 加载或卸载 JVM 时,也会涉及 JVM 的退出操作。

八、JVM 的发展历程

从Sun Classic VM到今天的HotSpot VM,JVM经历了多次重大更新和改进。如今,无论是服务器端应用还是移动开发,HotSpot VM都占据了主导地位。此外,Oracle的Graal VM以其跨语言全栈虚拟机的特性,预示着未来Java生态的新方向。

JVM 与 Java 体系结构是 Java 开发领域的核心知识,无论是在实际项目开发中的性能优化、问题排查,还是在面试中的脱颖而出,都具有不可替代的作用。深入学习和理解 JVM,能够让开发者站在更高的视角审视 Java 程序的运行机制,编写出更加高效、稳定的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/972122.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出 Python Logging:从基础到进阶日志管理

在 Python 开发过程中,日志(Logging)是不可或缺的调试和监控工具。合理的日志管理不仅能帮助开发者快速定位问题,还能提供丰富的数据支持,让应用更具可观测性。本文将带你全面了解 Python logging 模块,涵盖…

设计模式15:中介者模式

系列总链接:《大话设计模式》学习记录_net 大话设计-CSDN博客 1.概述 中介者模式(Mediator Pattern)是一种行为设计模式,旨在通过一个中介对象来封装一系列对象之间的交互方式,从而减少这些对象间的直接依赖。在该模式…

爬取网站内容转为markdown 和 html(通常模式)

我们遇到一些自己喜欢内容,想保存下来,手动复制粘贴很麻烦,我们使用 python 来爬取这些内容。 一、代码 downlod.py import os import requests from bs4 import BeautifulSoup from urllib.parse import urljoin# 目标网页(可…

【Linux】命令操作、打jar包、项目部署

阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 一:Xshell下载 1:镜像设置 二:阿里云设置镜像Ubuntu 三&#xf…

Unity合批处理优化内存序列帧播放动画

Unity合批处理序列帧优化内存 介绍图片导入到Unity中的处理Unity中图片设置处理Unity中图片裁剪 创建序列帧动画总结 介绍 这里是针对Unity序列帧动画的优化内容,将多个图片合批处理然后为了降低Unity的内存占用,但是相对的质量也会稍微降低。可自行进行…

day4 多连联表慢查询sql查询优化

1.Explain分析sql语句出现的字段是什么意思 id: 查询的序列号,表示查询中 select 子句或操作表的顺序。 如果 id 相同,则执行顺序从上到下。 如果 id 不同,如果是子查询,id 的值会递增,id 值越大优先级越高&#xff0c…

基于豆瓣2025电影数据可视化分析系统的设计与实现

✔️本项目旨在通过对豆瓣电影数据进行综合分析与可视化展示,构建一个基于Python的大数据可视化系统。通过数据爬取收集、清洗、分析豆瓣电影数据,我们提供了一个全面的电影信息平台,为用户提供深入了解电影产业趋势、影片评价与演员表现的工…

力扣高频sql 50题(基础版) :NULL, 表连接,子查询,case when和avg的结合

NULL的处理 nvl(字段,num) 和数字进行比较需要先使用nvl(字段,num)函数处理空值 思路: 没有被id 2 的客户推荐>> 过滤条件 referee_id !2 没有被id 2 的客户推荐>>被其他客户推荐, 但是也有可能没有被任何客户推荐>>NULL 考点: NULL是 不一个具体的数…

夜莺监控发布 v8.beta5 版本,优化 UI,新增接口认证方式便于鉴权

以防读者不了解夜莺,开头先做个介绍: 夜莺监控,英文名字 Nightingale,是一款侧重告警的监控类开源项目。类似 Grafana 的数据源集成方式,夜莺也是对接多种既有的数据源,不过 Grafana 侧重在可视化&#xff…

Python - 爬虫利器 - BeautifulSoup4常用 API

文章目录 前言BeautifulSoup4 简介主要特点:安装方式: 常用 API1. 创建 BeautifulSoup 对象2. 查找标签find(): 返回匹配的第一个元素find_all(): 返回所有匹配的元素列表select_one() & select(): CSS 选择器 3. 访问标签内容text 属性: 获取标签内纯文本get_t…

认识 ADB(Android Debug Bridge,Android SDK 中的一个工具)

一、ADB 概述 ADB,全称 Android Debug Bridge,是 Android SDK 中的一个工具 ADB 位于 Android SDK 下 platform-tools 目录中 ADB 起到调试桥的作用,ADB 可以让开发者通过 USB 连接安卓设备,并在电脑上执行各种命令,…

模拟解决哈希表冲突

目录 解决哈希表冲突原理: 模拟解决哈希表冲突代码: 负载因子: 动态扩容: 总结: HashMap和HashSet的总结: 解决哈希表冲突原理: 黑色代表一个数组,当 出现哈希冲突时&#xff0…

FPGA简介|结构、组成和应用

Field Programmable Gate Arrays(FPGA,现场可编程逻辑门阵列),是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物, 是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的&#xff0c…

【机器学习】超参数调优指南:交叉验证,网格搜索,混淆矩阵——基于鸢尾花与数字识别案例的深度解析

一、前言:为何要学交叉验证与网格搜索? 大家好!在机器学习的道路上,我们经常面临一个难题:模型调参。比如在 KNN 算法中,选择多少个邻居(n_neighbors)直接影响预测效果。 • 蛮力猜…

UGUI RectTransform的SizeDelta属性

根据已知内容,SizeDelta offsetMax - offsetMin 1.锚点聚拢情况下 输出 那么此时SizeDelta就是UI元素的长宽大小 2. 锚点分散时 引用自此篇文章中的描述 揭秘!anchoredPosition的几何意义! SizeDelta offsetMax - offsetMin (rectMax…

51单片机入门_10_数码管动态显示(数字的使用;简单动态显示;指定值的数码管动态显示)

接上篇的数码管静态显示,以下是接上篇介绍到的动态显示的原理。 动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选&#xff…

mybatis使用typeHandler实现类型转换

使用mybatis作为操作数据库的orm框架,操作基本数据类型时可以通过内置的类型处理器完成java数据类型和数据库类型的转换,但是对于扩展的数据类型要实现与数据库类型的转换就需要自定义类型转换器完成,比如某个实体类型存储到数据库&#xff0…

瑞萨RA-T系列芯片ADCGPT功能模块的配合使用

在马达或电源工程中,往往需要采集多路AD信号,且这些信号的优先级和采样时机不相同。本篇介绍在使用RA-T系列芯片建立马达或电源工程时,如何根据需求来设置主要功能模块ADC&GPT,包括采样通道打包和分组,GPT触发启动…

最新智能优化算法:牛优化( Ox Optimizer,OX)算法求解经典23个函数测试集,MATLAB代码

一、牛优化算法 牛优化( OX Optimizer,OX)算法由 AhmadK.AlHwaitat 与 andHussamN.Fakhouri于2024年提出,该算法的设计灵感来源于公牛的行为特性。公牛以其巨大的力量而闻名,能够承载沉重的负担并进行远距离运输。这种…

【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用

【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用 文章目录 【linux】在 Linux 服务器上部署 DeepSeek-r1:70b 并通过 Windows 远程可视化使用个人配置详情一、安装ollama二、下载deepseek版本模型三、在 Linux 服务器上配置 Ollama 以允许远程访…