【JVM 深入了解】JVM 到底包含什么?

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主

⛪️ 个人社区:个人社区
💞 个人主页:个人主页
🙉 专栏地址: ✅ Java 中级
🙉八股文专题:剑指大厂,手撕 Java 八股文

在这里插入图片描述

文章目录

      • 1. JVM 架构
      • 2. 垃圾收集机制
      • 3. 性能优化
      • 4. 内存模型
      • 5. 类加载过程
      • 6. 字节码执行
      • 7. 常见问题与调试
      • 8. 最佳实践

Java 虚拟机(JVM, Java Virtual Machine)是 Java 平台的核心组件,它负责执行 Java 字节码。JVM 提供了一个跨平台的运行环境,使得 Java 程序可以在不同的操作系统上运行而无需重新编译。以下是关于 JVM 的一些关键内容:

1. JVM 架构

JVM 主要由以下几个部分组成:

  • 类加载器子系统(Class Loader Subsystem)

    • 引导类加载器(Bootstrap Class Loader):加载核心 Java 类库(如 java.lang.*)。
    • 扩展类加载器(Extension Class Loader):加载 Java 扩展库(位于 jre/lib/ext 目录下的类库)。
    • 应用程序类加载器(Application Class Loader):加载用户自定义的应用程序类。
  • 运行时数据区(Runtime Data Area)

    • 方法区(Method Area):存储类的结构信息,如运行时常量池、字段和方法数据、构造函数和普通方法的字节码内容等。
    • 堆(Heap):存储对象实例和数组。堆是所有线程共享的内存区域。
    • 虚拟机栈(VM Stack):每个线程都有一个私有的虚拟机栈,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
    • 本地方法栈(Native Method Stack):与虚拟机栈类似,但为本地方法服务。
    • 程序计数器(Program Counter Register):记录当前线程所执行的字节码指令地址。
  • 执行引擎(Execution Engine)

    • 解释器(Interpreter):逐条解释并执行字节码。
    • 即时编译器(Just-In-Time Compiler, JIT):将热点代码编译成本地机器码,提高执行效率。
    • 垃圾收集器(Garbage Collector, GC):自动管理内存,回收不再使用的对象。
    • 本地接口(Native Interface):与本地方法库交互,调用本地方法。
  • 本地方法库(Native Method Libraries)

    • 包含了特定平台相关的本地方法实现,如文件 I/O、网络通信等。

2. 垃圾收集机制

JVM 的垃圾收集机制主要负责自动管理内存,回收不再使用的对象。常见的垃圾收集算法包括:

  • 标记-清除(Mark and Sweep)

    • 标记阶段:从根集合开始遍历,标记所有可达的对象。
    • 清除阶段:回收未被标记的对象。
  • 复制(Copying)

    • 将存活对象从一个空间复制到另一个空间,然后清空原来的内存空间。
  • 标记-整理(Mark and Compact)

    • 标记阶段:标记所有可达的对象。
    • 整理阶段:将存活对象向一端移动,然后清理边界外的内存。
  • 分代收集(Generational Collection)

    • 将堆分为新生代(Young Generation)和老年代(Old Generation),针对不同代采用不同的收集策略。
    • 新生代通常使用复制算法,老年代通常使用标记-整理或标记-清除算法。

3. 性能优化

  • JIT 编译器

    • 通过将热点代码编译成本地机器码,提高执行效率。
    • 可以通过 -XX:CompileThreshold 参数调整触发 JIT 编译的阈值。
  • 垃圾收集器选择

    • 不同的垃圾收集器适用于不同的场景,如 Serial GC、Parallel GC、CMS GC 和 G1 GC。
    • 可以通过 -XX:+UseSerialGC-XX:+UseParallelGC-XX:+UseConcMarkSweepGC-XX:+UseG1GC 等参数选择合适的垃圾收集器。
  • 堆大小设置

    • 通过 -Xms-Xmx 参数设置初始堆大小和最大堆大小。
    • 合理设置堆大小可以避免频繁的垃圾收集和 OutOfMemoryError。
  • 其他优化参数

    • -XX:NewRatio:设置新生代和老年代的比例。
    • -XX:SurvivorRatio:设置 Eden 区和 Survivor 区的比例。
    • -XX:MaxTenuringThreshold:设置晋升老年代的最大年龄。
    • -XX:ParallelGCThreads:设置并行垃圾收集的线程数。

4. 内存模型

JVM 的内存模型规定了多线程环境下对共享变量的访问规则,主要包括:

  • 主内存与工作内存

    • 每个线程都有自己的工作内存,存储了该线程读写共享变量的副本。
    • 主内存中存储了所有的共享变量。
  • 原子性、可见性和有序性

    • 原子性:保证基本数据类型的读写操作是原子的。
    • 可见性:确保一个线程对共享变量的修改对其他线程是可见的。
    • 有序性:禁止编译器和处理器对指令进行重排序。
  • volatile 关键字

    • 保证变量的可见性和有序性。
    • 防止指令重排序。
  • synchronized 关键字

    • 保证代码块的原子性和可见性。
    • 通过监视器锁(Monitor Lock)实现互斥访问。

5. 类加载过程

类加载过程主要包括以下步骤:

  • 加载(Loading)

    • 通过类的全限定名获取二进制流。
    • 将二进制流转换为方法区内的运行时数据结构。
    • 在内存中生成一个代表这个类的 java.lang.Class 对象。
  • 验证(Verification)

    • 确保被加载的类符合 JVM 规范,防止恶意代码破坏 JVM 安全。
  • 准备(Preparation)

    • 为类的静态变量分配内存,并设置默认初始值。
  • 解析(Resolution)

    • 将符号引用替换为直接引用。
  • 初始化(Initialization)

    • 执行类构造器 <clinit>() 方法,初始化静态变量和静态代码块。

6. 字节码执行

  • 字节码

    • Java 源代码经过编译后生成的中间表示形式。
    • 字节码是一种平台无关的二进制格式。
  • 解释执行

    • 解释器逐条解释并执行字节码。
  • 即时编译

    • JIT 编译器将热点代码编译成本地机器码,提高执行效率。

7. 常见问题与调试

  • OutOfMemoryError

    • 堆内存溢出(Heap Space):增加堆内存大小。
    • 栈内存溢出(Stack Overflow):检查递归调用深度。
    • 方法区内存溢出(PermGen 或 Metaspace):增加方法区大小。
  • 性能监控工具

    • JConsole:图形化监控工具,可以查看 JVM 的内存使用情况、线程状态等。
    • VisualVM:更强大的图形化监控工具,支持性能分析、内存快照等功能。
    • jstat:命令行工具,用于监控 JVM 的性能统计信息。
    • jmap:命令行工具,用于生成堆转储快照。
    • jstack:命令行工具,用于打印线程堆栈跟踪信息。

8. 最佳实践

  • 合理设置堆大小

    • 根据应用的实际需求设置 -Xms-Xmx,避免频繁的垃圾收集。
  • 选择合适的垃圾收集器

    • 根据应用的特点选择适合的垃圾收集器,如低延迟应用可以选择 G1 GC。
  • 减少不必要的对象创建

    • 使用对象池、缓存等技术减少对象的创建和销毁。
  • 使用并发编程

    • 利用多线程提高应用的并发处理能力,但要注意线程安全问题。
  • 定期进行性能分析

    • 使用性能监控工具定期分析应用的性能瓶颈,进行针对性优化。

JVM 是 Java 应用程序运行的基础,理解 JVM 的架构、垃圾收集机制、性能优化、内存模型、类加载过程等内容对于开发高性能、可靠的 Java 应用至关重要。通过合理的配置和最佳实践,可以显著提升应用的性能和稳定性。

精彩专栏推荐订阅:在下方专栏👇🏻
✅ 2023年华为OD机试真题(A卷&B卷)+ 面试指导
✅ 精选100套 Java 项目案例
✅ 面试需要避开的坑(活动)
✅ 你找不到的核心代码
✅ 带你手撕 Spring
✅ Java 初阶

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/460456.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

炫酷的登录框!(附源码)

大家想看什么前端效果请留言 预览效果 源码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>登录页…

MYSQL-SQL-03-DQL(Data Query Language,数据查询语言)(单表查询)

DQL&#xff08;数据查询语言&#xff09; DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记录。 查询关键字: SELECT 在一个正常的业务系统中&#xff0c;查询操作的频次是要远高于增删改的&#xff0c;当我们去访…

从理解路由到实现一套Router(路由)

小伙伴们大家好啊&#xff0c;我是李牌牌。平时在Vue项目中经常用到路由&#xff0c;但是也仅仅处于会用的层面&#xff0c;很多基础知识并不是真正的理解。于是牌牌呢查阅了很多资料&#xff0c;总结下路由相关的知识&#xff0c;查缺不漏&#xff0c;加深自己对路由的理解。 …

MFC图形函数学习04——画矩形函数

MFC中绘制矩形函数是MFC的基本绘图函数&#xff0c;它的大小和位置由左上角和右下角的坐标决定&#xff1b;若想绘制的矩形边框线型、线宽、颜色以及填充颜色都还需要其它函数的配合。 一、绘制矩形函数 原型&#xff1a;BOOL Rectangle(int x1,int y1,int x2,int y2); …

Kafka 与传统 MQ 消息系统之间有三个关键区别?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka 与传统 MQ 消息系统之间有三个关键区别&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; Kafka 与传统 MQ 消息系统之间有三个关键区别&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 …

TLKS-PMG-100BM这款输电线路智能多目视频监控装置,它具体有哪些亮点和优势?

TLKS-PMG-100BM输电线路智能多目视频监控装置&#xff08;输电线路全景视频监控装置、输电线路云台变焦视频监控装置&#xff09;无疑是一款功能全面、性能卓越的输电线路智能监控装置。它配备了水平360、垂直90旋转的全向云台摄像头&#xff0c;能够轻松实现全景视野监视&…

Java中的运算符【与C语言的区别】

目录 1. 算术运算符 1.0 赋值运算符&#xff1a; 1.1 四则运算符&#xff1a; - * / % 【取余与C有点不同】 1.2 增量运算符&#xff1a; - * / % * 【右侧运算结果会自动转换类型】 1.3 自增、自减&#xff1a;、-- 2. 关系运算符 3. 逻辑运算符 3.1 短路求值 3.2 【…

目标检测:YOLOv11(Ultralytics)环境配置,适合0基础纯小白,超详细

目录 1.前言 2. 查看电脑状况 3. 安装所需软件 3.1 Anaconda3安装 3.2 Pycharm安装 4. 安装环境 4.1 安装cuda及cudnn 4.1.1 下载及安装cuda 4.1.2 cudnn安装 4.2 创建虚拟环境 4.3 安装GPU版本 4.3.1 安装pytorch&#xff08;GPU版&#xff09; 4.3.2 安装ultral…

HT7178 带输出关断的20V,14A全集成同步升压转换器

1、特点 输入电压范围VpIN:2.7V-20V 输出电压范围VouT:4.5V-20V 可编程峰值电流:14A 高转换效率: 95%(VPIN7.2V, VoUT 16V, IouT3A) 94%(VPIN12V,VoUT18V,IoUT4A) 90%(VPIN3.3, VoUT-9V,IOUT3A) 轻载条件下两种调制方式:脉频调制(PFM)和 强制脉宽调试(PWM) 集成输出关断的栅极…

使用axios请求分页

npm install axios <template><div><el-table :data"items" style"width: 100%"><el-table-column prop"id" label"ID" /><el-table-column prop"name" label"名称" /><!-- 添…

基于SpringBoot的在线医疗问答平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

codeforces _ 补题

C. Ball in Berland 传送门&#xff1a;Problem - C - Codeforces 题意&#xff1a; 思路&#xff1a;容斥原理 考虑 第 i 对情侣组合 &#xff0c;男生为 a &#xff0c;女生为 b &#xff0c;那么考虑与之匹配的情侣 必须没有 a | b &#xff0c;一共有 k 对情侣&#x…

【Canvas与图标】长方形牛皮纸文件袋图标

【成图】 120*120的图标 大图 小图&#xff1a; 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>长方文件袋图标</title>…

奔走相告! ClickHouse 全新构建了强大的 JSON 数据类型

本文字数&#xff1a;8969&#xff1b;估计阅读时间&#xff1a;23 分钟 作者&#xff1a;Pavel Kruglov 本文在公众号【ClickHouseInc】首发 简介 JSON 已成为现代数据系统中处理半结构化和非结构化数据的首选格式。无论是在日志记录和可观测性 (observability) 应用场景、实…

统信UOS下启动图形界面应用工具manager报错:No protocol specified的解决办法

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、问题情况 达梦提供了丰富的图形界面工具&#xff0c;包括&#xff1a;manager、monitor、dbca等&#xff0c;但在统信操作系统进入终端去启动manager时报错&#xff1a;No protocol specified。 咨询了达…

【CSS3】css开篇基础(6)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

【设计模式系列】迭代器模式(七)

一、什么是迭代器模式 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;它提供一种方法来顺序访问一个聚合对象中的各个元素&#xff0c;而不暴露其内部的表示。迭代器模式将集合的遍历过程封装在一个独立的迭代器对象中&#xff0c;这样…

Linux线程安全(二)条件变量实现线程同步

目录 条件变量 条件变量初始化和唤醒 键盘触发条件变量唤醒线程demo 条件变量的等待 条件变量定时等待demo 条线变量实现多线程间的同步 条件变量 条件变量是为了控制多个线程的同步工作而设计的 比如说一个系统中有多个线程的存在但有且仅有一个线程在工作&#xff0c…

数据结构---顺序表

文章目录 线性表顺序表的使用及其内部方法ArrayList 的扩容机制顺序表的几种遍历方式顺序表的优缺点顺序表的模拟实现杨辉三角扑克牌算法 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&a…

大模型,多模态大模型面试【LoRA,分类,动静态数据类型,DDPM,ControlNet,IP-Adapter, Stable Diffusion】

大模型&#xff0c;多模态大模型面试【LoRA&#xff0c;分类&#xff0c;动静态数据类型&#xff0c;DDPM&#xff0c;ControlNet&#xff0c;IP-Adapter, Stable Diffusion】 问题一&#xff1a;LoRA是用在节省资源的场景下&#xff0c;那么LoRA具体是节省了内存带宽还是显存呢…