JVM 基础入门

一、JVM 基础认知

1. JVM 的定位

JVM 是 Java 代码与操作系统之间的中间层,屏蔽了不同操作系统的差异,实现 "一次编写,多次执行"。其核心是基于 Class 文件规范,任何语言(Java、Scala、Kotlin 等)只要能编译生成符合规范的 Class 文件,均可在 JVM 上运行。

主流 JVM 实现:Oracle HotSpot(JDK8 默认),其他包括 JRockit、GraalVM 等。

2. Java 文件执行流程

二、类加载机制(JDK8)

1. 类加载核心流程

2. 双亲委派机制

  • 核心逻辑:子类加载器加载类时,先委托父类加载器查找,父类无法加载时才自行加载("向上委托查找,向下委托加载")。
  • 类加载器体系(JDK8):
  • 核心作用:沙箱保护,防止自定义类覆盖 JDK 核心类(如java.lang.String)。
  • 打破双亲委派场景:Tomcat 需要加载多个 web 应用的独立类(不同应用同名类需隔离)。

3. 沙箱保护机制

  • 核心代码:ClassLoader.preDefineClass 方法禁止加载以java.开头的类,直接抛出SecurityException,避免核心类被篡改。

4. 类与对象的关系

  • 类信息存储:JDK8 中类的元数据(版本、注解、方法结构等)存储在元空间(MetaSpace),而非堆内存;JDK8 之前存储在永久代(PermGen)。
  • 元空间特性:
    • 逻辑上属于堆,物理上独立,可通过-XX:MetaspaceSize(初始大小)和-XX:MaxMetaspaceSize(最大大小)配置。
    • 支持 GC,但回收效率低,仅自定义类加载器加载的类可能被回收。
  • 对象与类的关联:堆中每个对象头部包含classpoint(类指针),指向元空间中的对应类信息,通过getClass()方法可获取。

三、JVM 内存模型(JDK8)

1. 内存区域划分

  • 核心参数:
    • 堆大小:-Xms(初始堆大小)、-Xmx(最大堆大小),生产环境建议设为相同值,避免内存扩展开销。
    • 年轻代与老年代比例:默认 1:2;Eden 与 Survivor 比例:默认 8:1:1(通过-XX:SurvivorRatio调整)。

2. 栈帧结构

每个方法执行时创建一个栈帧,包含:

  • 局部变量表:存储方法参数和局部变量,以 Slot 为最小单位(1 个 Slot 可存基本类型 / 对象引用)。
  • 操作数栈:存储计算过程中的中间结果,配合字节码指令执行。
  • 动态链接:指向运行时常量池的方法引用,支持方法动态调用。
  • 返回地址:记录方法调用者的指令地址。

四、执行引擎

1. 执行方式分类

执行方式 原理 优缺点
解释执行 逐行翻译字节码为机器指令,即时执行 启动快,执行慢
编译执行(JIT) 提前将热点代码编译为机器指令存入 CodeCache 启动慢,执行快
混合执行(默认) 先解释执行,热点代码触发 JIT 编译 平衡启动速度和执行效率
AOT 编译(GraalVM) 直接将 Java 代码编译为机器指令(无 JVM 依赖) 执行快,跨平台性差

2. JIT 编译器(HotSpot)

  • C1 编译器(客户端编译器):简单优化,编译快,适用于桌面应用。
  • C2 编译器(服务端编译器):激进优化,编译慢但执行效率高,适用于服务器应用(JDK8 默认)。
  • 分层编译:结合 C1 和 C2 优势,分 5 个层次动态调整编译策略,平衡启动速度和执行效率。

3. 静态执行与动态执行

  • 静态执行:编译期确定执行方法(如静态方法、私有方法)。
  • 动态执行:运行时确定执行方法(如重载方法、接口方法),依赖invokedynamic指令支持。

五、垃圾回收(GC)

1. GC 核心目标

自动回收堆内存中不再被引用的对象,避免内存泄漏,保障程序稳定运行。

2. 分代收集模型(JDK8 默认)

  • 核心假设:80% 的对象 "朝生夕死",少数对象长期存活。
  • 回收流程:
  • 关键概念:
    • YoungGC(MinorGC):回收年轻代,触发频繁,回收速度快。
    • OldGC(MajorGC):回收老年代,触发频率低,回收速度慢。
    • FullGC:回收整个堆 + 元空间,性能开销大,应尽量避免。

3. 垃圾回收器分类(JDK8 及以后)

4. GC 参数配置与日志分析

(1)核心 GC 参数
参数类型 常用参数 说明
堆配置 -Xms2G -Xmx2G 初始 / 最大堆大小均为 2G
年轻代配置 -XX:SurvivorRatio=8 Eden:S0:S1=8:1:1
日志打印 -XX:+PrintGCDetails -Xloggc:gc.log 打印详细 GC 日志到文件
回收器指定 -XX:+UseParallelGC 使用 Parallel Scavenge(JDK8 默认)
-XX:+UseConcMarkSweepGC 使用 CMS 回收器
(2)GC 日志分析工具
  • 在线工具:GCeasy(支持日志上传,自动分析问题并给出优化建议)。
  • 关键指标:GC 触发频率、GC 停顿时间、内存回收效率、FullGC 次数(过多时需优化)等等。
相关推荐
Derek_Smart1 天前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
大道至简Edward1 天前
深入 JVM 核心:一文读懂 Class 文件结构(附 Hex 实战解析)
jvm
weisian1515 天前
JVM--20-面试题6:如何判断对象可以被垃圾回收?
jvm·可达性算法
蚊子码农5 天前
每日一题--JVM线程分析与死锁排查
jvm
xuxie995 天前
NEXT 1 进程2
java·开发语言·jvm
weisian1515 天前
JVM--19-面试题5:说说JVM的类加载机制和双亲委派模型
jvm·双亲委派模型·jvm类加载机制
亓才孓5 天前
【反射机制】
java·javascript·jvm
Volunteer Technology5 天前
JVM之性能优化
jvm·python·性能优化
Andy Dennis5 天前
Java语法注意事项
java·开发语言·jvm
坚持的小马5 天前
JVM相关笔记-jps
jvm·笔记