当前位置: 首页 > news >正文

JVM基础--JVM的组成

目录

前言

JVM整体架构

1. 类装载器子系统(Class Loader Subsystem)

1.1 装载(Loading)

1.2 链接(Linking)

1.3 初始化(Initialization)

2. 运行时数据区域(Runtime Data Area)

2.1 线程共享区域

方法区(Method Area)

堆(Heap)​编辑

2.2 线程私有区域

程序计数器(PC Register)

Java虚拟机栈(JVM Stack)

本地方法栈(Native Method Stack)

3. 执行引擎(Execution Engine)

3.1 解释器(Interpreter)

3.2 即时编译器(JIT Compiler)

3.3 垃圾收集器(Garbage Collector)

4. JVM内存模型示意图

5. 实际应用中的调优建议

5.1 堆内存调优

5.2 垃圾收集器选择

5.3 JIT编译优化

总结


前言

Java虚拟机(JVM)作为Java语言的核心基础设施,承担着将Java字节码转换为机器码并执行的重要职责。理解JVM的组成结构,对于Java开发者来说至关重要,它不仅能帮助我们写出更高效的代码,还能在遇到性能问题时快速定位和解决。本文将详细介绍JVM的各个组成部分及其工作原理。

JVM整体架构

JVM可以分为三大主要区域:

  • 类装载器子系统(Class Loader Subsystem)
  • 运行时数据区域(Runtime Data Area)
  • 执行引擎(Execution Engine)

让我们逐一深入了解这些组件。

1. 类装载器子系统(Class Loader Subsystem)

类装载器负责将.class文件加载到JVM内存中,这个过程包含三个步骤:

1.1 装载(Loading)

  • 启动类装载器(Bootstrap ClassLoader):加载核心Java API(如java.lang.*包)
  • 扩展类装载器(Extension ClassLoader):加载扩展目录中的类库
  • 应用程序类装载器(Application ClassLoader):加载用户自定义的类

1.2 链接(Linking)

  • 验证(Verification):确保字节码文件的正确性
  • 准备(Preparation):为类变量分配内存并设置默认初始值
  • 解析(Resolution):将符号引用转换为直接引用

1.3 初始化(Initialization)

执行类构造器<clinit>()方法,完成静态变量的赋值和静态代码块的执行。

2. 运行时数据区域(Runtime Data Area)

这是JVM内存管理的核心部分,分为线程共享和线程私有两类区域。

2.1 线程共享区域

方法区(Method Area)
  • 存储内容:类信息、常量、静态变量、即时编译器编译后的代码
  • Java 8之前:永久代(PermGen)实现
  • Java 8及之后:元空间(Metaspace)实现,使用本地内存
堆(Heap)
  • 年轻代(Young Generation)

    • Eden区:新对象分配的主要区域
    • Survivor区:分为S0和S1,存放经过一次GC后存活的对象
  • 老年代(Old Generation)

    • 存放长期存活的对象
    • 当对象在年轻代经过多次GC仍然存活时,会被晋升到老年代

2.2 线程私有区域

程序计数器(PC Register)
  • 记录当前线程执行的字节码指令地址
  • 线程切换时能够恢复到正确的执行位置
  • 如果执行的是Native方法,则计数器值为空
Java虚拟机栈(JVM Stack)

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

  • 局部变量表:存储方法参数和局部变量
  • 操作数栈:进行算术运算的工作区域
  • 动态链接:指向运行时常量池的引用
  • 方法返回地址:方法正常退出或异常退出的返回信息
本地方法栈(Native Method Stack)

为虚拟机使用到的Native方法服务,与Java虚拟机栈作用类似。

3. 执行引擎(Execution Engine)

执行引擎负责执行字节码指令,主要包含以下组件:

3.1 解释器(Interpreter)

逐行解释执行字节码指令,启动快但执行效率相对较低。

3.2 即时编译器(JIT Compiler)

  • 作用:将热点代码编译成本地机器码
  • 优势:显著提高代码执行效率
  • 类型
    • C1编译器:客户端编译器,编译速度快
    • C2编译器:服务端编译器,优化程度高

3.3 垃圾收集器(Garbage Collector)

自动管理内存,回收不再使用的对象,主要算法包括:

  • 标记-清除算法
  • 复制算法
  • 标记-整理算法
  • 分代收集算法

4. JVM内存模型示意图

5. 实际应用中的调优建议

5.1 堆内存调优

# 设置堆的初始大小和最大大小
-Xms512m -Xmx2g# 设置年轻代大小
-Xmn512m# 设置Survivor区比例
-XX:SurvivorRatio=8

5.2 垃圾收集器选择

# 使用G1垃圾收集器
-XX:+UseG1GC# 设置GC停顿时间目标
-XX:MaxGCPauseMillis=200

5.3 JIT编译优化

# 设置热点代码编译阈值
-XX:CompileThreshold=10000

总结

JVM的组成结构设计精巧,各个组件协同工作,为Java程序提供了稳定高效的运行环境。理解这些组件的作用和工作原理,能够帮助开发者:

  1. 写出更高效的代码:了解内存分配机制,减少不必要的对象创建
  2. 进行性能调优:根据应用特点调整JVM参数
  3. 排查线上问题:快速定位内存泄漏、GC问题等
  4. 选择合适的垃圾收集器:根据应用场景选择最适合的GC策略
http://www.lryc.cn/news/577088.html

相关文章:

  • AlpineLinux安装部署elasticsearch
  • STM32——HAL库总结
  • 详解快速排序
  • http相关网络问题面试怎么答
  • 矩阵的逆 线性代数
  • Vue中keep-alive结合router实现部分页面缓存
  • 【NLP 实战】蒙古语情感分析:从 CNN 架构设计到模型训练的全流程解析(内附项目源码及模型成果)
  • 【Flask开发】嘿马文学web完整flask项目第2篇:2.用户认证,Json Web Token(JWT)【附代码文档】
  • Nginx漏洞处理指南
  • python pyecharts 数据分析及可视化(2)
  • Prompt工程标准化在多模型协同中的作用
  • swift-19-从OC到Swift、函数式编程
  • 设计模式 | 过滤器模式
  • MySQL之全场景常用工具链
  • MyBatis批量删除
  • 【系统分析师】2021年真题:案例分析-答案及详解
  • CppCon 2017 学习:Type Punning in C++17 Avoiding Pun-defined Behavior
  • 【硬核数学】2.4 驯服“梯度下降”:深度学习中的优化艺术与正则化技巧《从零构建机器学习、深度学习到LLM的数学认知》
  • Python爬虫:Requests与Beautiful Soup库详解
  • ISP Pipeline(9):Noise Filter for Chroma 色度去噪
  • node js入门,包含express,npm管理
  • 用户行为序列建模(篇八)-【阿里】DIEN
  • ROS常用的路径规划算法介绍
  • 在Linux系统中部署Java项目
  • 爪形行列式
  • 图书管理系统练习项目源码-前后端分离-使用node.js来做后端开发
  • Linux中ssh无法使用配置的环境变量,ssh(非登录环境)环境变量和登录环境变量不同步问题
  • python中多线程:线程插队方法join详解、线程停止、通过变量来让线程停止
  • 电子计数跳绳原型
  • StarRocks 3.5 新特性解读:Snapshot 快照恢复、大导入性能全面升级、分区管理更智能