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

【从零开始学习JVM | 第一篇】快速了解JVM

前言: 

        在探索现代软件开发的丰富生态系统时,我们不可避免地会遇到一个强大而神秘的存在——Java虚拟机(JVM)。作为Java语言最核心的组成之一,JVM已经超越了其最初的设计目标,成为一个多语言的运行平台,支撑着企业级应用、大数据处理、移动应用等众多领域的技术栈。

JVM的独特之处在于它的架构设计,它不仅负责代码的执行,还包括了内存管理、垃圾回收、线程同步等高级功能,这些都是确保高效、稳定运行Java程序的关键因素。随着时间的推移,JVM经过不断的迭代和优化,集成了越来越多先进的性能改进技术,如即时编译(JIT)、热点代码检测、逃逸分析等。

而在本文中,我将为大家从基础层面介绍一下JVM,带领大家揭开JVM的神秘面纱。

目录

前言: 

什么是JVM 

1.JVM的功能:

2.常见的JVM:

3.JVM的组成部分:

总结:


什么是JVM 

        Java虚拟机(JVM)是一个可以执行Java字节码的虚拟计算机。它是Java平台的核心部分,负责运行以Java编程语言编写并编译为Java字节码(.class文件)的程序。JVM的存在使得Java语言能够实现其标志性的“一次编写,到处运行”(Write Once, Run Anywhere,WORA)的特性,因为JVM屏蔽了底层操作系统和硬件平台的差异

我们可以通过以下流程图来了解JVM在JAVA程序中的作用

总结来讲:我们平时自己写的代码需要编译后转为字节码,而JVM再将字节码转为机器码,提交给电脑进行运行。而JVM的功能也不止这些。

1.JVM的功能:

  1. 跨平台性:Java语言使用“一次编写,到处运行”(Write Once, Run Anywhere,WORA)的理念,JVM是这一理念的实现基础。开发者只需编写一次Java代码,然后编译成与平台无关的字节码文件,这些字节码可以在任何安装了兼容JVM的设备上运行。

  2. 内存管理:JVM管理Java程序运行时所需的内存。它包括堆内存(Heap)用于存储对象实例,栈内存(Stack)用于存储局部变量和调用方法的上下文,方法区(Method Area)用于存储类信息,以及其他如程序计数器等结构。JVM还负责垃圾回收(Garbage Collection),自动管理对象的生命周期,回收不再使用的对象占用的内存空间

  3. 执行引擎:JVM中的执行引擎负责解释字节码或通过即时编译器(Just-In-Time Compiler, JIT)将字节码转换为本地机器码执行,从而提高程序的性能。

  4. 安全性:JVM提供了一个相对封闭和安全的执行环境,可以对加载的字节码进行验证,确保其不会执行非法操作。JVM的安全管理器和类加载器也参与到安全检查中,防止恶意代码损害系统。

  5. 多语言支持:虽然JVM最初是为Java语言设计的,但现在它也支持其他语言,如Scala、Kotlin、Groovy等,甚至支持非JVM语言通过特定桥接技术运行在JVM上,如JRuby(Ruby语言的实现)和Jython(Python语言的实现)。

  6. 工具和生态系统:JVM提供了丰富的工具和API,如JConsole、VisualVM等,用于监控和调试运行在JVM上的程序。此外,围绕JVM形成了强大的生态系统,包括各种框架、库和工具,这些都大大增强了Java开发的便捷性和效率。

在这些功能中,即时编译是提升JAVA运行效率的最核心手段,因此我们这里来详细介绍一下即时编译

即时编译:

        在程序运行时将热点代码(经常执行的代码区域)编译成与本地平台相关的机器码,并且保存在本地。这样的话,当这些代码再次执行时就可以直接运行机器码,而不需要再次解释,从而大大提高了执行效率 。

即时编译的步骤:

  1. 热点探测:JIT编译器会监控哪些代码块(如方法或循环)被频繁执行,这些代码块被称为“热点代码”。

  2. 编译优化:当热点代码被识别后,JIT编译器会将这些代码编译成优化后的本地机器码。这个过程中,JIT编译器还会进行各种优化,比如内联展开、死码消除、循环优化等,以进一步提升性能。

  3. 代码替换:编译完成后,JVM会使用生成的机器码替换原先的字节码,之后的执行就不再需要解释器参与。

  4. 垃圾回收:即时编译生成的机器码也需要管理,当某部分代码不再是热点代码,或者JVM需要释放资源时,JIT编译器生成的机器码可能会被垃圾回收器清理掉。

2.常见的JVM:

  1. Oracle HotSpot JVM:这是目前最流行的JVM实现,是Oracle公司的产品。HotSpot JVM具有良好的性能和可靠性,并且具有广泛的平台支持。

  2. OpenJDK JVM:这是一个开源的JVM实现,是Oracle HotSpot JVM的基础。OpenJDK JVM由全球开发者社区维护和更新,提供了一种免费的Java运行环境。

  3. IBM JVM:这是IBM(国际商业机器公司)开发的JVM实现,具有较高的性能和可靠性。IBM JVM主要用于IBM的服务器和企业级应用程序。

  4. Azul Zing JVM:这是由Azul Systems开发的JVM实现,专注于提供卓越的性能和可伸缩性。Azul Zing JVM适用于高要求的应用程序,如金融交易系统和大规模数据处理。

  5. GraalVM:这是一种新型的JVM实现,由Oracle开发。GraalVM是一款高性能的JVM,同时还支持其他编程语言,如JavaScript、Python和Ruby。

我们可以使用cmd快速查看自己的虚拟机:

 这里标识我的虚拟机是 OpenJDK 11.0.16.1版本的Java虚拟机(JVM),并且它是64位的服务器版(Server VM)。这个特定的JVM构建是由Microsoft维护或构建的,支持混合模式执行(mixed mode),即能够在JIT编译模式和解释模式之间切换,以便在不同的场景下提供最佳性能。

3.JVM的组成部分:

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

    • 负责从文件系统或网络等来源加载Class文件,Class文件在文件形式中是以二进制流的形式存在的,类加载器读取这些字节流,并将其转换成方法区的运行时数据结构。
    • 在加载的过程中,类加载器还负责对字节码进行验证,确保其符合JVM规范,不会危害到JVM自身的安全。
    • 类加载器通常分为启动(Bootstrap)类加载器、扩展(Extension)类加载器和应用程序(Application)类加载器等。
  2. 运行时数据区(Runtime Data Areas)

    • 方法区(Method Area):存储每一个类的结构信息,如运行时常量池(Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容等。
    • 堆(Heap):JVM管理的最大一块内存区域,用于存放对象实例和数组,是垃圾收集器管理的主要区域。
    • 栈(Stacks:每个线程包含一个栈,用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法调用都会创建一个栈帧。
    • 程序计数器(Program Counter Register):每个线程都有一个程序计数器,是一块较小的内存空间,它指示了线程当前正在执行的JVM指令地址。
    • 本地方法栈(Native Method Stack):专门用于处理本地方法的调用。
  3. 执行引擎(Execution Engine)

    • 负责执行类文件中的指令。当执行引擎接收到字节码时,它会进行解释或编译(通过即时编译器,JIT)成为本地机器指令执行。
    • 包括解释器(Interpreter)和即时编译器(Just-In-Time Compiler, JIT)两部分。解释器快速解释执行字节码,而JIT编译器则可以提高性能,将热点代码(经常执行的代码)编译成与本地平台相关的机器码。
  4. 垃圾回收器(Garbage Collector)

    • 用于自动管理JVM内存,特别是堆内存的分配与释放。当对象不再被引用时,垃圾回收器会回收这些对象占用的内存空间,释放资源。
  5. 本地方法接口(JNI)与本地方法库(Native Libraries)

    • Java Native Interface(JNI)是一个框架,允许Java代码和其他语言写的代码互相调用,比如C/C++编写的应用程序或库。
    • 本地方法库是一组特定于特定操作系统的库,由JNI调用,用于执行那些不能直接用Java实现的任务。

JVM的这些组成部分共同工作,提供了一个完整、高效且稳定的Java运行时环境。通过不断地优化和改进这些组件,JVM能够支持高性能的并发和垃圾回收策略,同时确保了跨平台的可移植性和安全性。

总结:

        在本文中我们为大家介绍了JVM的基本组成和各个部分的功能,相信通过这一部分的讲解,大家已经能够理解JVM的作用。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关文章:

  • mysql中NULL值
  • 设计模式——单例模式(Singleton Pattern)
  • 基于单片机音乐盒仿真仿真系统设计
  • css实现头部占一定高度,内容区占剩余高度可滚动
  • Qt 容器QGroupBox带有标题的组框框架
  • SpringBoot集成Elasticsearch8.x(9)|(RestClient实现Elasticsearch DSL操作)
  • deepface:实现人脸的识别和分析
  • 3GPP标准查看、下载和几个UE相关系列标准
  • Transformer源码(带注释)
  • 机器学习中Fine-tuning应用实例
  • nginx配置正向代理支持https
  • 判断上三角矩阵
  • ORACLE使用Mybatis-plus批量插入
  • 12月12日作业
  • 2024年AI云计算专题研究报告:智算带来的变化
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【译】理解JavaScript:new 关键字
  • CAP理论的例子讲解
  • Debian下无root权限使用Python访问Oracle
  • egg(89)--egg之redis的发布和订阅
  • JavaScript异步流程控制的前世今生
  • linux学习笔记
  • Mysql数据库的条件查询语句
  • MySQL数据库运维之数据恢复
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • Odoo domain写法及运用
  • react-native 安卓真机环境搭建
  • vue自定义指令实现v-tap插件
  • windows下使用nginx调试简介
  • 初识 webpack
  • 给初学者:JavaScript 中数组操作注意点
  • 关于for循环的简单归纳
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 如何在 Tornado 中实现 Middleware
  • 深度解析利用ES6进行Promise封装总结
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 探索 JS 中的模块化
  • NLPIR智能语义技术让大数据挖掘更简单
  • zabbix3.2监控linux磁盘IO
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • #define,static,const,三种常量的区别
  • (MATLAB)第五章-矩阵运算
  • (二)hibernate配置管理
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (转)visual stdio 书签功能介绍
  • ******之网络***——物理***
  • .NET Micro Framework初体验(二)
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .Net的DataSet直接与SQL2005交互
  • .Net小白的大学四年,内含面经
  • .net中我喜欢的两种验证码
  • [Android]使用Retrofit进行网络请求
  • [CF703D]Mishka and Interesting sum/[BZOJ5476]位运算
  • [DM复习]关联规则挖掘(下)