JVM是什么?
JVM全称为Java Virtual Machine,直译为Java虚拟机,是运行Java字节码的虚拟计算机。它是Java平台的核心组件,负责将Java字节码转换为特定操作系统的机器指令并执行。JVM给予了内存管理、垃圾回收、安全性等机制,使得Java程序能够实现“一次编写,到处运行”的特性。
知识点字节码。只要符合JVM规范,任何语言生成的字节码都能在JVM上执行。例如Kotlin、Scala、Jython等知名语言,都可以凭借编译器生成JVM字节码并运行。就是:JVM只能运行Java代码吗?事实并非如此。JVM与Java语言并无必然联系,它实际运行的
JVM是怎么工作的?
JVM的完整执行流程如下:
java命令启动JVM- 创建引导类加载器并加载核心Java类库
- 创建主线程并执行main()方法
- 遇到新类时触发类加载过程
- 方法调用时创建栈帧,局部变量入栈
- 执行引擎解释或编译执行字节码
- 对象创建在堆内存分配空间
- 内存不足时触发垃圾回收
- 程序结束或异常终止时JVM退出

主要步骤
一、类加载过程
加载(Loading):
- 通过类加载器(ClassLoader)查找并加载类的二进制材料
- 常见的类加载器包括:Bootstrap ClassLoader(加载Java核心类)、Extension ClassLoader(加载扩展类)、Application ClassLoader(加载应用程序类)和自定义ClassLoader
验证(Verification):
- 确保加载的类符合JVM规范
- 包括文件格式验证、元材料验证、字节码验证和符号引用验证
准备(Preparation):
- 为类变量(static变量)分配内存并设置初始值(零值)
- 例如:static int a = 10; 在此阶段a会被初始化为0而非10
解析(Resolution):
- 将符号引用转换为直接引用
- 涉及类、接口、字段和途径的解析
初始化(Initialization):
- 执行类构造器()技巧
- 为静态变量赋予程序员指定的初始值
关键知识点:Java类加载器和双亲委派模型
二、运行时资料区域管理
JVM在运行时管理多个内存区域:
程序计数器(Program Counter Register):
- 线程私有
- 记录当前线程执行的字节码行号
Java虚拟机栈(JVM Stack):
- 线程私有
- 存储栈帧(Stack Frame),包含局部变量表、操作数栈、动态链接和方法返回地址
- 每个技巧调用会创建一个新的栈帧
本地方法栈(Native Method Stack):
- 线程私有
- 为JVM使用到的本地方法服务
Java堆(Heap):
- 线程共享
- 存储所有对象实例和数组
- GC关键管理区域
- 分为新生代(Eden、Survivor)和老年代
方法区(Method Area):
- 线程共享
- 存储类信息、常量、静态变量、即时编译器编译后的代码等
- 在HotSpot JVM中也称为"永久代"(PermGen)或"元空间"(Metaspace)

三、执行引擎
解释执行:
- 逐行解释字节码并执行
- 启动快但执行效率低
即时编译(JIT):
- 热点代码(Hot Spot)会被编译为本地机器码
- 编译后执行效率高
- HotSpot JVM采用分层编译策略
知识点:逃逸分析。逃逸分析是编译器优化的一部分,用于分析对象的动态作用域。编译器会检查对象的生命周期是否仅限于当前方法或线程,从而决定是否可以进行栈分配或锁消除等优化。
逃逸分析的结果直接影响以下优化:
- 栈上分配(Stack Allocation):将未逃逸的对象分配在栈帧上,减少堆内存压力。
- 标量替换(Scalar Replacement):将对象拆解为基本类型变量,消除对象头开销。
- 同步消除(Lock Elision):若对象未逃逸到其他线程,移除不必要的同步锁。
- 垃圾收集(GC):
- 自动内存管理机制
- 常见GC算法:标记-清除、标记-整理、复制算法
- 常见GC收集器:Serial、Parallel、CMS、G1等
- Serial收集器
单线程工作的收集器,采用标记-复制算法。在垃圾回收时会暂停所有用户线程(Stop-The-World),适合内存资源受限的客户端场景。新生代和老年代可分别启用-XX:+UseSerialGC参数。 - Parallel Scavenge收集器
多线程并行收集器,采用标记-复制算法(新生代)和标记-整理算法(老年代)。注重吞吐量优化,通过-XX:+UseParallelGC启用。提供-XX:MaxGCPauseMillis和-XX:GCTimeRatio参数调整停顿时间与吞吐量。 - ParNew收集器
Parallel Scavenge的变种,需与CMS配合使用。通过-XX:+UseParNewGC启用,采用多线程标记-复制算法。在JDK9后被标记为废弃,推荐使用G1替代。 - CMS收集器
并发标记清除收集器,采用标记-清除算法。通过-XX:+UseConcMarkSweepGC启用,分为初始标记、并发标记、重新标记和并发清除四个阶段。缺点是会产生内存碎片,且无法处理浮动垃圾。 - G1收集器
面向服务端的收集器,采用标记-整理算法和Region内存布局。通过-XX:+UseG1GC启用,支持预测停顿时间模型。将堆划分为多个Region,通过Remembered Set避免全堆扫描。 - ZGC收集器
低延迟收集器,采用染色指针和读屏障技术。通过-XX:+UseZGC启用,支持TB级堆内存,停顿时间不超过10ms。基于Region设计,实现并发标记-整理算法。
四、本地方法接口
JNI(Java Native Interface):
- 允许Java代码调用本地手段(C/C++编写)
- 给予与操作系统交互的能力
JVM通过这种精细的工作流程,完成了Java的"一次编写,到处运行"的特性,同时保证了程序执行的效率和安全性。
浙公网安备 33010602011771号