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

图1.2 JIT的编译思想图
源码论证
流程图先放在最前面,如图1.3

图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 选择城市定位 根据城市首字母分类排序
获取城市首字母排序,按字母顺序排序 <template><view class"address-wrap" id"address"><!-- 搜索输入框-end --><template v-if"!isSearch"><!-- 城市列表-start --><view class"address-sc…...
flex盒子 center排布,有滚动条时,拖动滚动条无法完整显示内容
文章目录 问题示例代码解决问题改进后的效果 问题 最近在开发项目的过程中,发现了一个有趣的事情,与flex盒子有关,不知道算不算是一个bug,不过对于开发者来说,确实有些不方便,感兴趣的同学不妨也去试试。 …...
Workbox使用分享
一、简要介绍 1.1 什么是Workbox 官方文档原文: 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 - 力扣(LeetCode) 通过做差可以得到利润序列,然后只要利润需求的非负数求和就可以,因为这里没有手续费,某天买入之后买出可以等价为这几天连续买入卖出 class Solution:def maxProfit(se…...
Python状态模式介绍、使用
一、Python状态模式介绍 Python状态模式(State Pattern)是一种行为型设计模式,它允许对象在不同的状态下表现不同的行为,从而避免在代码中使用多重条件语句。该模式将状态封装在独立的对象中,并根据当前状态选择不同的…...
Github-Copilot初体验-Pycharm插件的安装与测试
引言: 80%代码秒生成!AI神器Copilot大升级 最近copilot又在众多独角兽公司的合力下,取得了重大升级。GitHub Copilot发布还不到两年, 就已经为100多万的开发者,编写了46%的代码,并提高了55%的编码速度。 …...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
