JIT详解

文章目录

  • JIT
        • 为什么说 Java 语言“编译与解释并存”?
    • JIT原理
      • JVM 架构简览
      • JIT 编译流程
      • JIT 编译器的实现
        • 优化策略
            • 方法内联
            • 逃逸分析

JIT

在Java中,JIT(Just-In-Time)编译器是Java虚拟机(JVM)的一个重要组成部分,它负责将Java字节码转换成特定平台的机器码。这个过程是在Java程序运行时进行的,而非传统的编译过程中。Java的JIT编译器的目的是提高程序的执行效率,特别是对于长时间运行的Java应用来说,JIT编译可以显著提高性能。

这里是Java中代码从编译到运行的基本流程:

  1. 编译到字节码:首先,Java源代码被编译成Java字节码(.class文件)。这一步是静态的,发生在程序运行之前。
  2. 类加载:当Java程序运行时,Java虚拟机(JVM)会加载这些字节码文件。
  3. 字节码解释执行:最初,JVM通过解释器逐条执行字节码。这意味着JVM读取每条指令,然后执行对应的操作。这种方式简单但效率不高。
  4. JIT编译:当JVM识别出某些方法或代码块被频繁调用(即“热点代码”),它会使用JIT编译器将这些热点代码从字节码编译成本地机器码。由于机器码可以直接在硬件上执行,这样可以显著提高程序的执行速度。
  5. 优化:JIT编译器在编译过程中还会进行各种优化,比如内联、循环展开等,这些优化可以进一步提升代码的执行效率。

Java 程序从源代码到运行的过程如下图所示

Java程序转变为机器代码的过程Java程序转变为机器代码的过程

我们需要格外注意的是 .class->机器码 这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT(Just in Time Compilation) 编译器,而 JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言

Java程序转变为机器代码的过程

JDK、JRE、JVM、JIT 这四者的关系如下图所示。

JDK、JRE、JVM、JIT 这四者的关系

为什么说 Java 语言“编译与解释并存”?

我们可以将高级编程语言按照程序的执行方式分为两种:

  • 编译型:编译型语言 会通过编译器将源代码一次性翻译成可被该平台执行的机器码。一般情况下,编译语言的执行速度比较快,开发效率比较低。常见的编译性语言有 C、C++、Go、Rust 等等。
  • 解释型:解释型语言会通过解释器一句一句的将代码解释(interpret)为机器代码后再执行。解释型语言开发效率比较快,执行速度比较慢。常见的解释性语言有 Python、JavaScript、PHP 等等。

编译型语言和解释型语言编译型语言和解释型语言

根据维基百科介绍:

为什么说 Java 语言“编译与解释并存”?

这是因为 Java 语言既具有编译型语言的特征,也具有解释型语言的特征。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class 文件),这种字节码必须由 Java 解释器来解释执行。

JIT原理

要深入理解Java中JIT(Just-In-Time)编译器的原理,我们需要从Java虚拟机(JVM)的架构和JIT编译的工作流程入手。

JVM 架构简览

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

  1. 类加载器(Class Loaders):负责加载类文件。
  2. 运行时数据区(Runtime Data Areas):存储各种运行时数据,包括堆(Heap)、栈(Stacks)、方法区(Method Area)、程序计数器(Program Counter Register)等。
  3. 执行引擎(Execution Engine):将字节码转换为机器码并执行。执行引擎中包括解释器(Interpreter)和JIT编译器。

JIT 编译流程

JIT编译器的工作流程大致如下:

  1. 解释执行:最初,执行引擎使用解释器逐条解释执行字节码。这种执行方式容易实现,但效率不高。
  2. 识别热点代码:JVM监控各个方法的执行情况,识别出被频繁执行的方法或代码块,即“热点代码”(Hot Spot Code)。
  3. 编译热点代码:JIT编译器将这些热点代码编译成相应平台的机器码。这个过程中,JIT编译器还会应用多种优化技术,比如方法内联、循环展开等,以提高代码的执行效率。
  4. 替换与执行编译生成的机器码将替换原先的字节码执行路径。当再次执行到这些代码时,JVM将直接执行对应的机器码,从而提高执行效率。

JIT 编译器的实现

Java中的JIT编译器实现较为复杂,主要体现在优化策略和代码生成上。比如,OpenJDK中就包含了一个非常著名的JIT编译器:HotSpot VM。

优化策略

JIT编译器在将字节码转换成机器码的过程中,会应用一系列的优化策略来提高程序的执行效率。这些优化策略主要包括:

  • 死码删除(Dead Code Elimination):编译器会识别并删除那些不会影响程序最终结果的代码段,例如永远不会被执行到的代码(dead code)。
  • 循环优化(Loop Optimization):循环是程序中常见的热点,因此循环优化是JIT编译器的重点。这包括循环展开(减少循环次数来减小循环开销)和循环融合等技术。
  • 方法内联(Method Inlining):将一个方法的内容直接替换到调用该方法的位置,以减少方法调用的开销。如果一个方法较小且频繁被调用,将其内联可以显著提高性能。
  • 逃逸分析(Escape Analysis):分析对象的作用域和生命周期,如果对象不会“逃逸”出方法或线程,可能会被优化成栈上分配,减少垃圾收集的压力。
方法内联

方法内联它会把一些短小的方法体,直接纳入目标方法的作用范围之内,就像是直接在代码块中追加代码。这样,就少了一次方法调用,执行速度就能够得到提升,这就是方法内联的概念。

可以使用 -XX:-Inline 参数来禁用方法内联,如果想要更细粒度的控制,可以使用 CompileCommand 参数,例如:

ini代码解读
复制代码-XX:CompileCommand=exclude,java/lang/String.indexOf

在 JDK 的源码里,也有很多被 @ForceInline注解的方法,这些方法,会在执行的时候被强制进行内联;而被@DontInline注解的方法,则始终不会被内联。

JIT 编译之后的二进制代码,是放在 Code Cache 区域里的。这个区域的大小是固定的,而且一旦启动无法扩容。如果 Code Cache 满了,JVM 并不会报错,但会停止编译。所以编译执行就会退化为解释执行,性能就会降低。不仅如此,JIT 编译器会一直尝试去优化你的代码,造成 CPU 占用上升。

通过参数 -XX:ReservedCodeCacheSize 可以指定 Code Cache 区域的大小,如果你通过监控发现空间达到了上限,就要适当的增加它的大小。

逃逸分析

下面着重讲解一下逃逸分析,这个知识点在面试的时候经常会被问到。

有这样一个问题:我们常说的对象,除了基本数据类型,一定是在堆上分配的吗?

答案是否定的,通过逃逸分析,JVM 能够分析出一个新的对象的使用范围,从而决定是否要将这个对象分配到堆上。逃逸分析现在是 JVM 的默认行为,可以通过参数-XX:-DoEscapeAnalysis 关掉它。

那什么样的对象算是逃逸的呢?可以看一下下面的两种典型情况。

如代码所示,对象被赋值给成员变量或者静态变量,可能被外部使用,变量就发生了逃逸。

public class EscapeAttr {Object attr;public void test() {attr = new Object();}
}

再看下面这段代码,对象通过 return 语句返回。由于程序并不能确定这个对象后续会不会被使用,外部的线程能够访问到这个结果,对象也发生了逃逸。

public class EscapeReturn {Object attr;public Object test() {Object obj = new Object();return obj;}
}

那逃逸分析有什么好处呢?

「1. 栈上分配」

如果一个对象在子程序中被分配,指向该对象的指针永远不会逃逸,对象有可能会被优化为栈分配。栈分配可以快速地在栈帧上创建和销毁对象,不用再分配到堆空间,可以有效地减少 GC 的压力。

「2. 分离对象或标量替换」

但对象结构通常都比较复杂,如何将对象保存在栈上呢?

JIT 可以将对象打散,全部替换为一个个小的局部变量,这个打散的过程,就叫作标量替换(标量就是不能被进一步分割的变量,比如 int、long 等基本类型)。也就是说,标量替换后的对象,全部变成了局部变量,可以方便地进行栈上分配,而无须改动其他的代码。

从上面的描述我们可以看到,并不是所有的对象或者数组,都会在堆上分配。由于JIT的存在,如果发现某些对象没有逃逸出方法,那么就有可能被优化成栈分配。

「3.同步消除」

如果一个对象被发现只能从一个线程被访问到,那么对于这个对象的操作可以不考虑同步。

注意这是针对 synchronized 来说的,JUC 中的 Lock 并不能被消除。

要开启同步消除,需要加上 -XX:+EliminateLocks 参数。由于这个参数依赖逃逸分析,所以同时要打开 -XX:+DoEscapeAnalysis 选项。

比如下面这段代码,JIT 判断对象锁只能被一个线程访问,就可以去掉这个同步的影响。

public class SyncEliminate {public void test() {synchronized (new Object()) {}}
}

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

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

相关文章

数据结构邻接表表示图的深度优先搜索遍历 有向图+无向图(C语言代码+终端输入内容)

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #define MAXVEX 20 //下面三个结构体就是邻接表的结构体&#xff0c;完全一样的方式 typedef struct EdgeNode {int adjvex;struct EdgeNode* next; }EdgeNode; typedef struct VertexNo…

sql数据库命令行操作(数据库的增删改查)

查询数据库 查询电脑里面所有数据库 SHOW DATABASES;查询当前所处的数据库 SELECT DATABASE();应用场景&#xff1a;当我使用了USE命令后不知道自己所在哪个数据库时&#xff0c;可以使用这个命令查询自己所在数据库 创建数据库 创建 CREATE DATABASE [IF NOT EXISTS] 数据…

UE4 材质学习笔记10(程序化噪波/覆雪树干着色器/岩层着色器)

一.程序化噪波 柏林噪波是一种能生成很好的随机图案的算法&#xff0c;它是一个无限的、不重复的图案&#xff0c;可以采用这种基础图案并以多种方式对其进行修改&#xff0c; 将它缩放并进行多次组合&#xff0c;就可以创建一个分形图案。这些组合的缩放等级称为一个Octave 这…

守护“视界”,手持式视力筛查仪解决方案

根据国家卫健委数据显示&#xff0c;2022年我国儿童青少年总体近视率为53.6%&#xff0c;整体近视率呈低龄高发态势&#xff0c;其中小学生为35.6%&#xff0c;初中生为71.1%&#xff0c;高中生甚至近视率高达80.5%。随着电视、电脑、平板、手机等电子设备深度侵入人们的生活&a…

力扣题31~40

题31&#xff08;中等&#xff09;&#xff1a; 分析&#xff1a; 其实这题题目比较难懂&#xff0c;题目还是挺简单的 我们可以从后面末尾开始&#xff0c;如果前一个大于后面的&#xff0c;说明后面不用动&#xff0c;如果小于&#xff0c;那就找仅仅大于它的数字放前面&…

iOS 18升级:避免常见陷阱,顺利完成升级

随着iOS 18的发布&#xff0c;许多用户都希望尽快体验到新系统带来的新功能和改进。然而&#xff0c;升级过程可能会因为准备工作不足或对步骤的不熟悉而变得复杂。本文旨在为用户提供一个清晰的升级指南&#xff0c;确保升级过程既平滑又安全。 升级前的准备工作 在开始升级之…

Linux操作系统小项目——实现《进程池》

文章目录 前言&#xff1a;代码实现&#xff1a;原理讲解&#xff1a;细节处理&#xff1a; 前言&#xff1a; 在前面的学习中&#xff0c;我们简单的了解了下进程之间的通信方式&#xff0c;目前我们只能知道父子进程的通信是通过匿名管道的方式进行通信的&#xff0c;这是因…

JAVA自动化测试TestNG框架

1.TestNG简介 JAVA自动化测试最重要的基石。官网&#xff1a;https://testng.org 使用注解来管理我们的测试用例。 发现测试用例 执行测试用例 判断测试用例 生成测试报告 2.创建Maven工程 2.1创建一个maven工程 2.2设置maven信息 2.3设置JDK信息 2.4引入testng依赖 <dep…

软考高级系统规划与管理师,都是精华知识点!

知识点&#xff1a;信息的定义和属性 1、 信息的基本概念 l 信息是客观事物状态和运动特征的一种普遍形式&#xff0c;客观世界中大量地存在、产生和传递着以这些方式表示出来的各种各样的信息。 l 维纳&#xff08;控制论创始人&#xff09;&#xff1a;信息就是信息&#…

指针——数据结构解惑

文章目录 一.取指针和解指针二.为什么用指针&#xff1f; 指针存的是地址 一.取指针和解指针 int main() {int a0;int * p ;//声明int类型的**指针**char * m ;//声明char类型的**指针**&a;//a是个变量&#xff0c;&a&#xff0c;把地址取出来p&a;//p指针存的a的地…

双十一性价比高的宠物空气净化器推荐,希喂、美的、352测评分享

不知不觉这一年就要过去了&#xff0c;别问我为什么这么感伤&#xff0c;因为双十一要来了&#xff0c;我要开始”剁手“了&#xff0c;尤其是必须得买宠物空气净化器。 因为我家里养了两只猫&#xff0c;超级爱掉毛&#xff0c;每天为了清理这些猫毛我都要烦死了&#xff0c;…

LangChain4j使用阿里云百炼 进行AI调用

LangChain4j 介绍 LangChain4j 是一个专为Java开发者设计的开源库&#xff0c;旨在简化将大型语言模型&#xff08;LLM&#xff09;集成到Java应用程序中的过程。它于2023年初开发&#xff0c;灵感来源于Python和JavaScript的LLM库&#xff0c;特别是为了填补Java领域在这一方面…

支持阅后即焚的笔记Enclosed

什么是 Enclosed &#xff1f; Enclosed 是一个简约的网络应用程序&#xff0c;旨在发送私人和安全的笔记。所有笔记均经过端到端加密&#xff0c;确保服务器和存储对内容一无所知。用户可以设置密码、定义有效期 (TTL)&#xff0c;并选择在阅读后让笔记自毁。 软件特点&#x…

软考高项一年只考一次,2025 年会更难考吗?

根据近几年的考试情况来看&#xff0c;可以推测25年的高项考试可能会更加困难。值得关注的是2024年的考试情况&#xff0c;当年的高项考试是第二次机考&#xff0c;考试形式已经相对稳定。上午考试的科目知识点分布保持稳定&#xff0c;包括1道综合计算题和2道分析题的案例分析…

决策树和集成学习的概念以及部分推导

一、决策树 1、概述 决策树是一种树形结构&#xff0c;树中每个内部节点表示一个特征上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff0c;每个叶子节点代表一种分类结果 决策树的建立过程&#xff1a; 特征选择&#xff1a;选择有较强分类能力的特征决策树生成…

【工欲善其事】巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号

文章目录 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号1 问题描述2 解决方案3 具体步骤4 效果测试5 小结与复盘 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号 1 问题描述 不知各位是否也为复制过来的文本中夹杂的回车换行符抓狂过&#xff1f;就是在复…

python 爬虫 入门 一、基础工具

目录 一&#xff0c;网页开发者工具的使用 二、通过python发送请求 &#xff08;一&#xff09;、get &#xff08;二&#xff09;、带参数的get &#xff08;三&#xff09;、post 后续&#xff1a;数据解析 一&#xff0c;网页开发者工具的使用 我们可以用 requests 库…

国际期货收费行情源CTP推送式/期货配资软件开发对接行情源的技术性说明

在现代金融市场中&#xff0c;期货交易因其高风险和高回报特性而备受关注。为了满足期货交易者的需求&#xff0c;开发高效、稳定和安全的期货交易软件变得尤为重要。本文将对国际期货收费行情源CTP推送式及期货配资软件的开发对接行情源的技术细节进行详细说明。 一、CTP&…

2024双十一值得购买的好物有哪些?看完这五款好物让你不后悔!

随着一年一度的双十一购物狂欢节即将拉开帷幕&#xff0c;作为一名热衷于分享购物心得的博主&#xff0c;我今天特别想在这里为大家详细介绍五款我个人非常期待入手的好物。这些产品都是经过我精心挑选和试用的&#xff0c;我相信它们不仅能够满足我的需求&#xff0c;同样也能…

visio导出pdf公式变形问题杂谈

其实不会变形。 我自己的情况是直接用edge PDF阅读器打开pdf看到的是公式有变形&#xff08;常见是字体、形状变了&#xff09;&#xff0c;但换一个pdf阅读器如adobe的就是正常的了 不过大家一般是用edge pdf阅读器直接打开查看&#xff0c;所以通过visio打印的方式导出pdf可…