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 次数(过多时需优化)等等。
相关推荐
蜂蜜黄油呀土豆3 小时前
深入解析 Java 虚拟机内存模型
jvm·内存管理·垃圾回收·java 性能优化
chilavert3183 小时前
技术演进中的开发沉思-330 : 虚拟机命令行工具
java·jvm
小北方城市网1 天前
Spring Boot 接口开发实战:RESTful 规范、参数校验与全局异常处理
java·jvm·数据库·spring boot·后端·python·mysql
chilavert3181 天前
技术演进中的开发沉思-328 JVM:垃圾回收(上)
java·开发语言·jvm
橙露1 天前
CGO性能深度剖析:成因、评估与优化全指南
java·jvm·myeclipse
chilavert3181 天前
技术演进中的开发沉思-329 JVM:垃圾回收(中)
java·jvm·算法
tqs_123451 天前
Java关键字、GC回收器与JVM调优详解
jvm·测试工具
0x531 天前
JAVA|智能仿真并发项目-进程与线程
java·开发语言·jvm
偷星星的贼111 天前
Python虚拟环境(venv)完全指南:隔离项目依赖
jvm·数据库·python