Salmon的全栈知识 Salmon的全栈知识
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
首页
  • JavaSE
  • JavaWeb
  • Spring生态
  • JUC
  • JVM
  • Netty
  • Java各版本特性
  • 23种设计模式
  • Maven
  • Java常用框架
  • Dubbo
  • OpenFeign
  • Nacos
  • Zookeeper
  • Sentinel
  • Seata
  • Gateway
  • Go基础
  • Gin
  • SQL数据库

    • MySQL
    • Oracle
  • NoSQL数据库

    • Redis
    • MongoDB
    • ElasticSearch
  • 消息中间件

    • RabbitMQ
    • RocketMQ
    • Kafka
    • ActiveMQ
    • MQTT
    • NATS
  • 网关中间件

    • Nginx
  • Linux
  • Docker
  • Git
  • K8s
  • Solidity
  • Java
  • 计算机网络
  • 操作系统
GitHub (opens new window)
npm

(进入注册为作者充电)

  • JVM基础

    • 初识JVM
      • 1. 什么是JVM
      • 2. JVM的功能
        • 2.1 解释和运行
        • 2.2 内存管理
        • 2.3 即时编译
        • Java性能低的主要原因和跨平台特性
      • 3. 常见的JVM
        • 3.1 Java虚拟机规范
        • 3.2 Java虚拟机规范
        • 3.3 HotSpot的发展历程
        • 初出茅庐 - 1999年4月
        • 野蛮生长 - 2006年12月
        • 稳步前进 - 2009-2013
        • 百家争鸣 - 2018-2019
        • 拥抱云原生 - 2019-至今
    • 字节码文件详解
    • 运行时数据区
    • 垃圾回收
  • JVM实战

    • 内存调优
    • GC调优
    • 性能调优
  • JVM高级

    • GraalVM
    • 新一代的GC
    • 揭秘Java工具
  • JVM原理

    • 栈上的数据存储
    • 对象在堆上是如何存储的?
    • 方法调用的原理
    • 异常捕获的原理
    • JIT即时编译器
    • 垃圾回收器原理
  • JVM面试

    • 什么是JVM?
    • 了解过字节码文件的组成吗?
    • 说一下运行时数据区
    • 哪些区域会出现内存溢出,会有什么现象?
    • JVM在JDK6-8之间在内存区域上有什么不同
    • 类的生命周期
    • 什么是类加载器?
    • 什么是双亲委派机制
    • 如何打破双亲委派机制
    • Tomcat的自定义类加载器
    • 如何判断堆上的对象没有被引用??
    • JVM 中都有哪些引用类型?
    • ThreadLocal中为什么要使用弱引用?
    • 有哪些常见的垃圾回收算法?
    • 有哪些常用的垃圾回收器?
    • 如何解决内存泄漏问题?
    • 常见的JVM参数?
  • 《JVM》笔记
  • JVM基础
Salmon
2024-03-11
目录
1. 什么是JVM
2. JVM的功能
2.1 解释和运行
2.2 内存管理
2.3 即时编译
Java性能低的主要原因和跨平台特性
3. 常见的JVM
3.1 Java虚拟机规范
3.2 Java虚拟机规范
3.3 HotSpot的发展历程
初出茅庐 - 1999年4月
野蛮生长 - 2006年12月
稳步前进 - 2009-2013
百家争鸣 - 2018-2019
拥抱云原生 - 2019-至今

初识JVM

# 1. 什么是JVM

JVM 全称是 Java Virtual Machine,中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件。

Java源代码执行流程如下:

img

分为三个步骤:

1、编写Java源代码文件。

2、使用Java编译器(javac命令)将源代码编译成Java字节码文件。

3、使用Java虚拟机加载并运行Java字节码文件,此时会启动一个新的进程。

# 2. JVM的功能

  • 1 - 解释和运行
  • 2 - 内存管理
  • 3 - 即时编译

# 2.1 解释和运行

对字节码文件中的指令,实时的解释成机器码,让计算机执行。

字节码文件中包含了字节码指令,计算器无法直接执行,Java虚拟机会将字节码文件中的字节码指令实时地解释成机器码,机器码是计算机可以运行的指令。

image-20240311151955569

# 2.2 内存管理

  • 自动为对象、方法等分配内存
  • 自动的垃圾回收机制,回收不再使用的对象

Java虚拟机会帮助程序员为对象分配内存,同时将不用的对象使用垃圾回收器回收掉,这是对比C和C++这些语言的一个优势。在C/C++语言中,对象的回收需要程序员手动去编写代码完成,如果遗漏了这段删除对象的代码,这个对象就会永远占用内存空间,不会再回收。所以JVM的这个功能降低了程序员编写代码的难度。

# 2.3 即时编译

对热点代码进行优化,提升执行效率。即时编译可以说是提升Java程序性能最核心的手段。

# Java性能低的主要原因和跨平台特性

Java语言如果不做任何的优化,性能其实是不如C和C++语言的。主要原因是:

在程序运行过程中,Java虚拟机需要将字节码指令实时地解释成计算机能识别的机器码,这个过程在运行时可能会反复地执行,所以效率较低。

image-20240311162605954

C和C++语言在执行过程中,只需要将源代码编译成可执行文件,就包含了计算机能识别的机器码,无需在运行过程中再实时地解释,所以性能较高。

image-20240311162630315

Java为什么要选择一条执行效率比较低的方式呢?主要是为了实现跨平台的特性。Java的字节码指令,如果希望在不同平台(操作系统+硬件架构),比如在windows或者linux上运行。可以使用同一份字节码指令,交给windows和linux上的Java虚拟机进行解释,这样就可以获得不同平台上的机器码了。这样就实现了Write Once,Run Anywhere 编写一次,到处运行 的目标。

image-20240311162652714

但是C/C++语言,如果要让程序在不同平台上运行,就需要将一份源代码在不同平台上分别进行编译,相对来说比较麻烦。

再回到即时编译,在JDK1.1的版本中就推出了即时编译去优化对应的性能。

image-20240311162711587

虚拟机在运行过程中如果发现某一个方法甚至是循环是热点代码(被非常高频调用),即时编译器会优化这段代码并将优化后的机器码保存在内存中,如果第二次再去执行这段代码。Java虚拟机会将机器码从内存中取出来直接进行调用。这样节省了一次解释的步骤,同时执行的是优化后的代码,效率较高。

Java通过即时编译器获得了接近C/C++语言的性能,在某些特定的场景下甚至可以实现超越。

# 3. 常见的JVM

# 3.1 Java虚拟机规范

  • 《Java虚拟机规范》由Oracle制定,内容主要包含了Java虚拟机在设计和实现时需要遵守的规范,主要包含class字节码文件的定义、类和接口的加载和初始化、指令集等内容。
  • 《Java虚拟机规范》是对虚拟机设计的要求,而不是对Java设计的要求,也就是说虚拟机可以运行在其他的语言比如Groovy、Scala生成的class字节码文件之上。
  • 官网地址:https://docs.oracle.com/javase/specs/index.html (opens new window)

# 3.2 Java虚拟机规范

平时我们最常用的,就是Hotspot虚拟机。

名称 作者 支持版本 社区活跃度(github star) 特性 适用场景
HotSpot (Oracle JDK版) Oracle 所有版本 高(闭源) 使用最广泛,稳定可靠,社区活跃JIT支持Oracle JDK默认虚拟机 默认
HotSpot (Open JDK版) Oracle 所有版本 中(16.1k) 同上开源,Open JDK默认虚拟机 默认对JDK有二次开发需求
GraalVM Oracle 11, 17,19企业版支持8 高(18.7k) 多语言支持高性能、JIT、AOT支持 微服务、云原生架构需要多语言混合编程
Dragonwell JDK龙井 Alibaba 标准版 8,11,17扩展版11,17 低(3.9k) 基于OpenJDK的增强高性能、bug修复、安全性提升JWarmup、ElasticHeap、Wisp特性支持 电商、物流、金融领域对性能要求比较高
Eclipse OpenJ9 (原 IBM J9) IBM 8,11,17,19,20 低(3.1k) 高性能、可扩展JIT、AOT特性支持 微服务、云原生架构

# 3.3 HotSpot的发展历程

# 初出茅庐 - 1999年4月

源自1997年收购的SmallTalk语言的虚拟机,HotSpot虚拟机初次在JDK中使用。在JDK1.2中作为附加功能存在,

JDK1.3之后作为默认的虚拟机。

# 野蛮生长 - 2006年12月

JDK 6发布,并在虚拟机层面做了大量的优化,这些优化对后续虚拟机的发展产生了深远的影响。

# 稳步前进 - 2009-2013

JDK7中首次推出了G1垃圾收集器。收购了Sun公司之后,吸纳了JRockIt虚拟机的一些设计思想,JDK8中引入了JMC等工具,去除了永久代。

# 百家争鸣 - 2018-2019

JDK11优化了G1垃圾收集器的性能,同时推出了ZGC新一代的垃圾回收器,JDK12推出Shenan-doah垃圾回收器。

# 拥抱云原生 - 2019-至今

以Hotspot为基础的GraalVM虚拟机诞生,不仅让解决了单体应用中多语言整合的难题,同时也提升了这些语言运行时的效率。极高的性能、极快的启动速度也更适用于当下的云原生架构。

上次更新: 2025/03/09, 18:29:07
字节码文件详解

字节码文件详解→

Theme by Vdoing | Copyright © 2022-2025 Salmon's Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式