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

JVM源码剖析之JIT工作流程

版本信息:

jdk版本:jdk8u40

思想至上

Hotspot中执行引擎分为解释器、JIT及时编译器,上篇文章描述到解释器过度到JIT的条件。JVM源码剖析之达到什么条件进行JIT优化 这篇文章大致讲述JIT的编译过程。在JDK中javac和JIT两部分跟编译原理挂钩,而编译原理抛开内部实现的算法,从思想的角度出发可以分为前端、中间IR、后端,见图1.1描述。比如拿javac举例,开发人员编写好xxx.java 文件,通过javac命令把xxx.java 文件编译成 xxx.class二进制文件交给JVM执行,其中编译的流程就如图1.1的流程。
图1.1 编译原理思想图
图1.1 编译原理思想图

而本文论述JIT,所以我们需要把编译原理的思想带入到JIT中,见图1.2,这里的输入为达到JIT编译阈值的方法对应的字节码,经过前端、中间IR语言、后端(这里为了容易理解,把前端、中间IR语言、后端想象成一个编译的黑盒程序)后得到输出结果为ISA指令集(ISA:CPU平台可执行指令)
图1.2 JIT的编译思想图
图1.2 JIT的编译思想图

源码论证

流程图先放在最前面,如图1.3
图1.3 JIT工作流程
图1.3 JIT工作流程

由图1.3可以得知Java工作线程(Java项目中运行的线程)和编译线程之间通过队列来通信(当然,这也是线程通信的最基本方式),CompileTask作为通信的载体,当Java线程执行某个方法当方法达到JIT优化的阈值或者回边计数器达到了阈值,此时会创建CompileTask投递到CompileQueue队列中。

/*
method_invocation_event->compile->submit_compile->compile_method->compile_method_base->create_compile_task
*/
// src/share/vm/compiler/compileBroker.cpp 文件中
CompileTask* CompileBroker::create_compile_task(CompileQueue* queue,int           compile_id,methodHandle  method,int           osr_bci,int           comp_level,methodHandle  hot_method,int           hot_count,const char*   comment,bool          blocking) {CompileTask* new_task = allocate_task();new_task->initialize(compile_id, method, osr_bci, comp_level,hot_method, hot_count, comment,blocking);// 给CompilerThread线程对应的队列投递编译任务。queue->add(new_task);return new_task;
}

java工作线程给编译线程队列投递任务后,此时编译线程开始干活,接收队列的compileTask任务,开始执行编译工作

// src/share/vm/compiler/compileBroker.cpp 文件中
void CompileBroker::compiler_thread_loop() {CompilerThread* thread = CompilerThread::current();// 拿到当前编译线程对应的队列CompileQueue* queue = thread->queue();…………while (!is_compilation_disabled_forever()) {// 从队列中获取到任务CompileTask* task = queue->get();if (task == NULL) {continue;}…………// 执行任务invoke_compiler_on_method(task);}
}

接下来的编译工作需要区分c1还是c2编译器,这个在Java工作线程投递compileTask任务的时候就已经确定(因为在检查阈值的时候即可确定)。在Hotspot中c1编译器用Compiler类作为抽象,c2编译器使用C2Compiler类作为抽象,不管是c1和c2都继承与AbstractCompiler,AbstractCompiler类中给予编译器公共的抽象。为了篇幅的简单,我们采用c1,也叫做client编译器。

/*
invoke_compiler_on_method->Compiler::compile_method(Compiler为c1编译器)->Compilation::Compilation->Compilation::compile_method
*/
// src/share/vm/c1/c1_Compilation.cpp 文件中
void Compilation::compile_method() {…………// compile methodint frame_size = compile_java_method();if (InstallMethods) {		// 在c1编译器中,默认为true,也即编译完成后安装机器码。// 安装代码(实际上就是把机器码执行地址放入Method对象中,下次执行方法就会执行JIT编译好的代码)install_code(frame_size);}…………
}int Compilation::compile_java_method() {// 从方法字节码构建出HIR中间语言。{PhaseTraceTime timeit(_t_buildIR);build_hir();}// 从HIR中间语言构建出LIR中间语言{PhaseTraceTime timeit(_t_emit_lir);_frame_map = new FrameMap(method(), hir()->number_of_locks(), MAX2(4, hir()->max_stack()));emit_lir();}// 从LIR中间语言生成机器代码{PhaseTraceTime timeit(_t_codeemit);return emit_code_body();}
}

在这里插入图片描述

整个c1编译器的编译过程就论述完毕了(仅仅是宏观上,微观上还存在众多算法和平台指令的生成,这个跟编译原理的算法和Hotspot中JIT优化的思想有关,这里不做论述)

这里对IR中间语言做一个简单的论述,为什么Hotspot中JIT需要存在HIR和LIR 2个中间语言呢?在编译原理中,IR的作用是承上启下,由于中间层的出现,这也让前端和后端更加灵活多变,此时,这也让笔者不经想起一句话" 计算机的世界没有加一个中间层解决不了的问题,如果不行,那就再加一层 ",并且有了中间层的出现,便可以在中间表示层做你想做的语言优化工作。说回Hotspot中,既然分了HIR(High-level Intermediate Representation)和LIR(Low-level Intermediate Representation)两层中间层,所以抽象的行为更加的具体,并且模块化更细粒度。HIR在JIT中是平台无关的中间语言,这一层完全可以用来对接字节码,并且做优化工作,优化完毕后,生成LIR中间语言,而LIR中间语言与平台相关,可以说已经非常接近平台相关指令(机器语言),这一层便可以做平台相关的优化工作。一层一层的过度,这像不像解释器过度到JIT的过程。

在GCC编译器中IR中间层就分为GENERIC、GIMPLE、RTL,也是一层一层的过度,最终RTL最接近机器语言的表现形式

在Coins编译器中,IR中间层也是分为HIR、LIR,跟Hotspot一样,从HIR过度到LIR,LIR接近机器语言的表现形式。

相关文章:

JVM源码剖析之JIT工作流程

版本信息: jdk版本:jdk8u40思想至上 Hotspot中执行引擎分为解释器、JIT及时编译器,上篇文章描述到解释器过度到JIT的条件。JVM源码剖析之达到什么条件进行JIT优化 这篇文章大致讲述JIT的编译过程。在JDK中javac和JIT两部分跟编译原理挂钩&a…...

【投资笔记】(23/7/31)下半年消费复苏的机会来了?

本文为本人投资逻辑验证,不作为任何建议; 政策面 汽车:(一)优化汽车购买使用管理(二)扩大新能源汽车消费,重点在于新能源汽车;房地产:(三&#x…...

MySQL二进制日志(binlog)配置、二进制日志binlog查看、mysqlbinlog查看二进制日志、二进制日志binlog清理等详解

提示:MySQL 中的日志比较重要的有 binlog(归档日志)、redo log(重做日志)以及 undo log,那么跟我们本文相关的主要是 binlog,另外两个日志松哥将来有空了再和大家详细介绍。 文章目录 1、二进制…...

Python内存管理解析:高效利用资源的关键

推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 引言 在当今互联网时代,Python已经成为最受欢迎的编程语言之一。它的简洁、灵活和强大的生态系统使其成为…...

解决Debian10乱码以及远程连接ssh的问题

文章目录 解决Debian10乱码Debian10配置ssh 解决Debian10乱码 下载locales apt-get install locales配置语言 dpkg-reconfigure locales输入上述命令后会进入到以下页面【空格为选中,回车下一个页面】 在这个页面里我们按空格选中如图的选项,然后回…...

C# 泛型(Generic)

方法重载:方法名称相同,参数个数和参数类型不同; 优势:可以节约方法名称 劣势:方法过多 语法:public void writeContent(T t) 原理:普通的C#代码他是运行在前端进行编译,所有的类型需…...

Golang之路---02 基础语法——流程控制(if-else , switch-case , for-range , defer)

流程控制 条件语句——if-else if 条件 1 {分支 1 } else if 条件 2 {分支 2 } else if 条件 ... {分支 ... } else {分支 else }注: Golang编译器,对于 { 和 } 的位置有严格的要求,它要求 else if (或 else)和 两边…...

HTTP——HTTP报文内的HTTP信息

HTTP 通信过程包括从客户端发往服务器端的请求及从服务器端返回客户端的响应。本章就让我们来了解一下请求和响应是怎样运作的。 HTTP 一、HTTP报文二、请求报文及响应报文的结构三、编码提升传输速率1、报文主体和实体主题的差异2、压缩传输的内容编码3、分割发送的分块传输编…...

RocketMQ工作原理

文章目录 三.RocketMQ工作原理1.消息的生产消息的生产过程Queue选择算法 2.消息的存储1.commitlog文件目录与文件消息单元 2.consumequeue目录与文件索引条目 3.对文件的读写消息写入消息拉取性能提升 3.indexFile1.索引条目结构2.文件名的作用3.查询流程 4.消息的消费1.推拉消…...

Jenkins+Docker+Docker-Compose自动部署,SpringCloud架构公共包一个任务配置

前言 Jenkins和docker的安装,随便百度吧,实际场景中我们很多微服务的架构,都是有公共包,肯定是希望一个任务能够把公共包的配置加进去,一并构建,ok,直接上干货。 Jenkins 全局环境安装 pwd e…...

spring boot 2 配置上传文件大小限制

一、起因:系统页面上传一个文件超过日志提示的文件最大100M的限制,需要更改配置文件 二、经过: 1、在本地代码中找到配置文件,修改相应数值后交给运维更新生产环境配置,但是运维说生产环境没有这行配置,遂…...

Jmeter —— 录制脚本

1. 第一步:添加http代理服务器,在测试计划--》添加--》非测试元件--》http代理服务器 2. 第二步:添加线程组(这个线程组是用来放录制的脚本,不添加也可以,就直接放在代理服务器下) 测试计划--》…...

从零开始学Docker(一):Docker的安装部署

前述:本次学习与整理来至B站【Python开发_老6哥】老师分享的课程,有兴趣的小伙伴可以去加油啦,附链接 宿主机环境:RockyLinux 9 版本管理 Docker引擎主要有两个版本:企业版(EE)和社区版&#…...

【ROS 02】ROS通信机制

机器人是一种高度复杂的系统性实现,在机器人上可能集成各种传感器(雷达、摄像头、GPS...)以及运动控制实现,为了解耦合,在ROS中每一个功能点都是一个单独的进程,每一个进程都是独立运行的。更确切的讲,ROS是进程&#…...

uniapp 选择城市定位 根据城市首字母分类排序

获取城市首字母排序&#xff0c;按字母顺序排序 <template><view class"address-wrap" id"address"><!-- 搜索输入框-end --><template v-if"!isSearch"><!-- 城市列表-start --><view class"address-sc…...

flex盒子 center排布,有滚动条时,拖动滚动条无法完整显示内容

文章目录 问题示例代码解决问题改进后的效果 问题 最近在开发项目的过程中&#xff0c;发现了一个有趣的事情&#xff0c;与flex盒子有关&#xff0c;不知道算不算是一个bug&#xff0c;不过对于开发者来说&#xff0c;确实有些不方便&#xff0c;感兴趣的同学不妨也去试试。 …...

Workbox使用分享

一、简要介绍 1.1 什么是Workbox 官方文档原文&#xff1a; At this point, service workers may seem tricky. There’s lots of complex interactions that are hard to get right. Network requests! Caching strategies! Cache management! Precaching! It’s a lot to r…...

秋招算法备战第32天 | 122.买卖股票的最佳时机II、55. 跳跃游戏、45.跳跃游戏II

122. 买卖股票的最佳时机 II - 力扣&#xff08;LeetCode&#xff09; 通过做差可以得到利润序列&#xff0c;然后只要利润需求的非负数求和就可以&#xff0c;因为这里没有手续费&#xff0c;某天买入之后买出可以等价为这几天连续买入卖出 class Solution:def maxProfit(se…...

Python状态模式介绍、使用

一、Python状态模式介绍 Python状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许对象在不同的状态下表现不同的行为&#xff0c;从而避免在代码中使用多重条件语句。该模式将状态封装在独立的对象中&#xff0c;并根据当前状态选择不同的…...

Github-Copilot初体验-Pycharm插件的安装与测试

引言&#xff1a; 80%代码秒生成&#xff01;AI神器Copilot大升级 最近copilot又在众多独角兽公司的合力下&#xff0c;取得了重大升级。GitHub Copilot发布还不到两年&#xff0c; 就已经为100多万的开发者&#xff0c;编写了46%的代码&#xff0c;并提高了55%的编码速度。 …...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...