简介
Java 虚拟机(JVM)是运行 Java 程序的抽象计算引擎。它屏蔽了底层硬件和操作系统的差异,使得 Java 程序具有“一次编写,到处运行”的跨平台能力。JVM 的主要组件包括类加载器、运行时数据区和执行引擎。Hotspot 是目前最流行的 JVM 实现。
JVM 能跨平台工作,主要是由于 JVM 屏蔽了与各个计算机平台相关的软件、硬件之间的差异。
JVM 简介
计算机体系结构
真实的计算机体系结构的核心部分包含:
- 指令集
- 计算单元(CPU)
- 寻址方式
- 寄存器
- 存储单元
Java 虚拟机(JVM)是运行 Java 程序的抽象计算引擎。它屏蔽了底层硬件和操作系统的差异,使得 Java 程序具有“一次编写,到处运行”的跨平台能力。JVM 的主要组件包括类加载器、运行时数据区和执行引擎。Hotspot 是目前最流行的 JVM 实现。
JVM 能跨平台工作,主要是由于 JVM 屏蔽了与各个计算机平台相关的软件、硬件之间的差异。
真实的计算机体系结构的核心部分包含:
JVM 提供了丰富的诊断和监控工具,用于分析 Java 应用的运行状态。命令行工具包括 jps、jstat、jmap、jstack、jcmd 等;图形化工具包括 JConsole、VisualVM、Arthas 等。熟练使用这些工具是排查性能问题和生产故障的必备技能。
Java 程序员免不了故障排查工作,所以经常需要使用一些 JVM 工具。
JDK 自带了一些实用的命令行工具来监控、分析 JVM 信息,掌握它们,非常有助于 TroubleShooting。
JVM 故障处理是 Java 运维和开发的核心技能。常见问题包括 CPU 飙升、内存泄漏、GC 停顿、线程死锁等。通过 jstack、jmap、jstat 等工具,配合日志分析和监控数据,可以系统性地定位和解决这些故障。
Java 应用出现线上故障,如何进行诊断?
我们在定位线上问题时要有一个整体的思路,顺藤摸瓜,才能较快的找到问题原因。
一般来说,服务器故障诊断的整体思路如下:

JVM 运行时数据区是 Java 程序执行时的内存布局。包括线程私有的程序计数器、虚拟机栈、本地方法栈,以及线程共享的 Java 堆和方法区。理解内存区域的划分是进行内存调优、排查 OOM 和 StackOverflow 等问题的基础。
JVM 在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。如下图所示:

类加载机制是 JVM 将 .class 文件中的类信息加载到内存中的过程。它包括加载、验证、准备、解析、初始化五个阶段。类加载器采用双亲委派模型,确保核心类库的安全性和一致性。理解类加载机制对于解决类冲突、实现热部署和自定义加载策略至关重要。
类是在运行期间动态加载的。
类的加载指的是将类的 .class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向 Java 程序员提供了访问方法区内的数据结构的接口。
垃圾收集(GC)是 JVM 自动回收不再使用的内存对象的机制。GC 通过可达性分析判断对象是否存活,并使用各种回收算法(复制、标记-清除、标记-整理)和收集器(Serial、Parallel、CMS、G1、ZGC)来管理内存。理解 GC 机制是进行性能调优和解决内存问题的关键。
程序计数器、虚拟机栈和本地方法栈这三个区域属于线程私有的,只存在于线程的生命周期内,线程结束之后也会消失,因此不需要对这三个区域进行垃圾回收。垃圾回收主要是针对 Java 堆和方法区进行。
【Java 虚拟机】专题深入剖析 JVM 的核心运行机制,涵盖运行时数据区(堆、栈、方法区)、垃圾收集算法与主流收集器(CMS、G1、ZGC)、字节码格式与类加载机制(双亲委派模型)等关键主题。同时涉及 JVM 性能调优方法论与常用诊断工具(Arthas、jstat、jmap、MAT),助力生产环境问题排查与性能优化。
JVM、Hotspot、运行时数据区、类加载器、JIT堆、方法区、元空间、虚拟机栈、OutOfMemoryErrorGC Roots、可达性分析、分代收集、CMS、G1字节码、常量池、字节码指令、ASM、ByteBuddy类加载机制、双亲委派、ClassLoader、热部署、SPIArthas、jstat、jmap、jstack、MATCPU 飙升、内存泄漏、OOM、GC 频繁、死锁-Xms、-Xmx、GC 日志、吞吐量、停顿时间Java 字节码是 Java 源代码编译后的中间表示形式,存储在 .class 文件中。字节码是一种平台无关的指令集,由 JVM 的解释器或 JIT 编译器执行。理解字节码结构有助于深入理解 Java 的编译、加载和执行机制,也是学习字节码增强技术(ASM、Javassist、ByteBuddy)的基础。
Java 字节码是 Java 虚拟机执行的一种指令格式。之所以被称之为字节码,是因为:Java 字节码文件(.class)是一种以 8 位字节为基础单位的二进制流文件,各个数据项严格按照顺序紧凑地排列在 .class 文件中,中间没有添加任何分隔符。整个 .class 文件本质上就是一张表。
JVM 调优是通过调整 JVM 参数来优化应用性能的过程。主要关注两个指标:停顿时间(延迟)和吞吐量。调优的核心包括选择合适的 GC、配置堆内存大小、调整新生代比例等。调优应基于 GC 日志和监控数据,而非猜测。
对于 JVM 调优来说,需要先明确调优的目标。
从性能的角度看,通常关注三个指标:
吞吐量(throughput) - 指不考虑 GC 引起的停顿时间或内存消耗,垃圾收集器能支撑应用达到的最高性能指标。停顿时间(latency) - 其度量标准是缩短由于垃圾啊收集引起的停顿时间或者完全消除因垃圾收集所引起的停顿,避免应用运行时发生抖动。垃圾回收频率 - 久发生一次指垃圾回收呢?通常垃圾回收的频率越低越好,增大堆内存空间可以有效降低垃圾回收发生的频率,但同时也意味着堆积的回收对象越多,最终也会增加回收时的停顿时间。所以我们只要适当地增大堆内存空间,保证正常的垃圾回收频率即可。