volatile的扩展分析(1)———分析JIT编译器优化

简介: volatile的扩展分析(1)———分析JIT编译器优化

前言

提示:最近在写volatile的时候,涉及到了编译器优化的部分内容,写在voaltile里内容有点臃肿,单独写一篇博客来聊聊好了,直接先上一段代码:

public class VolatileClass {
    private static boolean isRunning = true;
    private static int i = 0;
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            while (isRunning) {
                i++;
            }
        });
        thread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        isRunning = false;
        System.out.println("isRunning has been changed to false");
    }
}

一、JIT 即时编译器的分类

我们知道,HotSpot集成了两个JIT compiler — C1及C2(或称为Client及Server)

两者的区别在于,前者没有应用激进的优化技术,因为这些优化往往伴随着耗时较长的代码分析。因此,C1的编译速度较快,而C2所编译的方法运行速度较快。

这两个JIT compiler(C1与C2)以及interpreter(解释器)将HotSpot的执行方式划分为五个级别:


level 0:interpreter解释执行

level 1:C1编译,无profiling(性能监控功能)

level 2:C1编译,仅方法及循环back-edge执行次数的profiling((性能监控功能))

level 3:C1编译,除level2中的profiling外还包括branch(针对分支跳转字节码)及receivertype(针对成员方法调用或类检测,如checkcast,instnaceof,aastore字节码)的profiling

level 4:C2编译

二、优化结果查看

1. 无volatile C2-level4级

7c5570fa6e6a4c68a57d152749e82020.png

可以看到jmp L0000 回跳到了inc 指令,也就是我们代码里的i++。换句话说,第一次进入循环会读我们的isRuning变量,读入寄存器后,做一个判断,但是也仅有一次判断。后续直接把循环判断的判断给去掉了,直接变成无限执行循环体了


2. 有volatile C2-level4级

我们对isRuning加了volatile,然后再运行看看情况

3b352695a22c48b3b1e9dc957c9c0da4.png

可以看到对isRuning加了volatile之后,编译器编译后的结果发生了改变,每次进行循环之前,会对isRuning再做一遍取值,如果不为0,则跳转到L0000,即满足条件再执行循环体的内容


目录
相关文章
|
3天前
|
存储 算法 编译器
C/C++编译器局部优化技术:局部优化是针对单个函数或基本块进行的优化
C/C++编译器局部优化技术:局部优化是针对单个函数或基本块进行的优化
39 0
|
3天前
|
监控 安全 Java
JVM工作原理与实战(三十八):JIT即时编译器原理
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了JIT即时编译器、HotSpot中的JIT编译器、JIT优化技术、JIT优化建议等内容。
14 0
|
3天前
|
缓存 编译器 程序员
C/C++编译器全局优化技术:全局优化是针对整个程序进行的优化,包括函数之间的优化
C/C++编译器全局优化技术:全局优化是针对整个程序进行的优化,包括函数之间的优化
32 0
|
3天前
|
设计模式 消息中间件 Java
面试官:什么是JIT、逃逸分析、锁消除、栈上分配和标量替换?
面试官:什么是JIT、逃逸分析、锁消除、栈上分配和标量替换?
559 1
|
9月前
|
缓存 安全 Java
volatile底层的实现原理:volatile关键字的作用、内存模型、JMM规范和CPU指令
volatile底层的实现原理:volatile关键字的作用、内存模型、JMM规范和CPU指令
125 0
|
10月前
|
存储 缓存 Java
volatile的扩展分析(2)——happens-before 与 内存屏障
volatile的扩展分析(2)——happens-before 与 内存屏障
84 0
volatile的扩展分析(2)——happens-before 与 内存屏障
|
存储 缓存 安全
基础篇:深入JMM内存模型解析volatile、synchronized的内存语义
总线锁定:当某个CPU处理数据时,通过锁定系统总线或者是内存总线,让其他CPU不具备访问内存的访问权限,从而保证了缓存的一致性
82 0
|
存储 Java 编译器
Java指令重排序在多线程环境下的应对策略
一、前言 指令重排在单线程环境下有利于提高程序的执行效率,不会对程序产生负面影响;在多线程环境下,指令重排会给程序带来意想不到的错误。 本文对多线程指令重排问题进行复原,并针对指令重排给出相应的解决方案。
84 0
|
存储 缓存 Java
JVM系列之:关于即时编译器的其他一些优化手段
JVM系列之:关于即时编译器的其他一些优化手段
94 0
JVM系列之:关于即时编译器的其他一些优化手段