JVM锁的优化与逃逸分析

锁消除

  • 是指JVM即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除
  • 锁消除的主要判定依据来源于逃逸分析的数据支持。
  • JIT(Just-In-Time,即时编译):是一种在程序运行时将部分热点代码编译成机器代码的技术,以提高程序的执行性能的机制。

将不存在并发的代码块上加的锁进行消除

逃逸分析

  • 1 栈上分配对象内存:如果确定一个对像被判定为不会逃逸出方法之外,那么我们就可以在栈上分配对象,随着方法的生命周期而被回收掉,也就不需要浪费在堆中分配对象并且通过复杂的gc操作的资源了。

  • 2 同步消除:线程同步本身就是个相对耗时的过程。如果逃逸分析能够确定一个变量不会逃逸出线程,无法被其他线程访问,也就是说该变量不会有同步竞争,也就可以将同步操作消除掉

  • 3 标量替换:如果逃逸分析能够确定一个对象不会被外部所访问,并且这个对象可以被拆散的话(拆散成一个个的标量(int long 以及reference类型)),创建若干个被这个方法使用到的成员变量来代替

    • 总结: 将原本需要分配在堆上的对象拆解成若干个基础数据类型存储在栈上,进一步减少堆空间的使用。

锁粗化

如果一系列的操作在同一个对象上反复加锁的场景下,我们可以使用锁粗化来进行优化。
如:for循环中加锁,或者StringBuffer的append操作(对StringBuffer加锁),这些场景下只加一次锁就可以了。

锁膨胀的过程

https://blog.csdn.net/fan1865221/article/details/96338419

  • 在 jdk6 之后便引入了“偏向锁”和“轻量级锁”,所以总共有4种锁状态,级别由低到高依次为:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态。
    这几个状态会随着竞争情况逐渐升级,此过程为不可逆。所以 synchronized 锁膨胀过程其实就是无锁 → 偏向锁 → 轻量级锁 → 重量级锁的一个过程。

[ˈmɑːnɪtər] monitor

  • 在使用 synchronized 来同步代码块的时候,编译后,会在代码块的起始位置插入 monitorenter指令,在结束或异常处插入 monitorexit指令
    当执行到 monitorenter 指令时,将会尝试获取对象所对应的 ** monitor **的所有权,即尝试获得对象的锁。而 synchronized 用的锁是存放在 Java对象头中的。
    所以引出了两个关键词:“Java 对象头” 和 “Monitor”

对象头中的 Mark Word 保存着锁的标志位: 无锁:01 偏向锁:01 轻量级锁:00 重量级锁:10

  • 1 无锁
  • 2 偏向锁:是指当一段同步代码一直被同一个线程所访问时,即不存在多个线程的竞争时,那么该线程在后续访问时便会自动获得锁,从而降低获取锁带来的消耗,即提高性能。
    • 当一个线程访问同步代码块并获取锁时,会在 Mark Word 里存储锁偏向的线程 ID。在线程进入和退出同步块时不再通过 CAS 操作来加锁和解锁,而是检测 Mark Word 里是否存储着指向当前线程的偏向锁。
      轻量级锁的获取及释放依赖多次 CAS 原子指令,而偏向锁只需要在置换 ThreadID 的时候依赖一次 CAS 原子指令即可。
    • 偏向锁只有遇到其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁,线程是不会主动释放偏向锁的
    • 偏向锁在 JDK 6 及之后版本的 JVM 里是默认启用的。可以通过 JVM 参数关闭偏向锁:-XX:-UseBiasedLocking=false,关闭之后程序默认会进入轻量级锁状态。
  • 3 轻量级锁:引入轻量级锁的主要目的是:在多线程竞争不激烈的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。
    • 需要注意的是轻量级锁并不是取代重量级锁,而是在大多数情况下同步块并不会出现严重的竞争情况,所以引入轻量级锁可以减少重量级锁对线程的阻塞带来的开销。
    • 所以偏向锁是认为环境中不存在竞争情况,而轻量级锁则是认为环境中不存在竞争或者竞争不激烈,所以轻量级锁一般都只会有少数几个线程竞争锁对象,
      其他线程只需要稍微等待(自旋)下就可以获取锁,但是自旋次数有限制,如果自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁膨胀为重量级锁,
  • 4 重量级锁使除了拥有锁的线程以外的线程都阻塞,防止CPU空转。

JVM自旋锁和自适应自旋锁优化

目的是降低线程执行行的cpu切换资源的消耗。

自旋锁

  • 如果当前有多个cpu,并且存在2个或2个以上的线程同时争夺同一资源时,我们就可以让后面那个请求锁的线程不放弃 CPU 的执行时间,而是自旋等待,如果锁被释放的同事就可以获取到锁资源,避免了线程切换带来的消耗

  • 但是也是有缺点的,如果锁资源被获取的时间比较长,那么自旋带来的消耗也是比较大的,占用大量的处理器cpu的时间

  • 所以,自旋等待的时间必须要有一定的限度,如果**自旋超过了限定次数(默认是10次,可以使用 -XX:PreBlockSpin 来更改)**没有成功获得锁,就应当挂起线程。

自适应自旋锁

自旋锁在 JDK1.4.2 中引入,使用 -XX:+UseSpinning 来开启。JDK 6 中变为默认开启,并且引入了自适应的自旋锁(适应性自旋锁)。

自适应自旋锁意味着自旋的时间(次数)不再固定,而是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。

  • 如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就会认为这次自旋也是很有可能再次成功,进而它将允许自旋等待持续相对更长的时间。比如:100个循环
  • 如果对于某个锁,自旋很少成功获得过锁,那在以后尝试获取这个锁时将可能省略掉自旋过程,直接阻塞线程,避免浪费处理器资源

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

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

相关文章

【STM32 Blue Pill编程】-定时器计数模式

定时器计数模式 文章目录 定时器计数模式1、定时器计数模式介绍2、硬件准备及接线3、模块配置3.1 定时器计数模式配置3.2 定时器中断配置3.3 串口配置4、代码实现在本文中,我们将讨论如何在计数器模式下配置 STM32 Blue Pill 定时器模块。 要将定时器用作计数器,我们将其配置…

【mechine learning-六-supervise learning之线性回归模型】

监督学习之线性回归模型 线性回归模型线性模型回归模型 如何使用线性模型实现智能化预测呢寻找数据训练模型输入、特征、目标、预测值、模型代价函数 线性模型是人工智能监督学习中最广泛的应用,所以有必要先学习一下这个基础模型,做好基石。 线性回归模…

在 CentOS 中永久关闭防火墙的步骤

在 CentOS 中永久关闭防火墙的步骤 在 CentOS 系统中,防火墙通常由 firewalld 服务管理。如果你希望在系统中永久关闭防火墙,可以按照以下步骤操作: 1. 停止防火墙服务 首先,你需要停止当前正在运行的防火墙服务。可以使用以下…

猎板PCB大讲堂:IPHONE16的线路板的升级猜测

iPhone 16 系列与 iPhone 15 系列在 PCB (印刷电路板) 设计上的主要差异可能体现在材料和技术上。根据 TrendForce 的分析,iPhone 16 预计将采用树脂涂覆铜箔(RCC)作为新的印刷电路板(PCB)材料,这一改变将使…

使用 ShuffleNet 模型在 CIFAR-100 数据集上的图像分类

简介 在深度学习领域,图像分类任务是衡量算法性能的重要基准。本文将介绍我们如何使用一种高效的卷积神经网络架构——ShuffleNet,来处理 CIFAR-100 数据集上的图像分类问题。 CIFAR-100 数据集简介 CIFAR-100 数据集是一个广泛使用的图像分类数据集&…

QT的绘画事件和网络通信

画一个时钟 #include "widget.h" #include "ui_widget.h" #include <QPainter> #include <QDebug> #include <QTime> #include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(…

11_跳表(Skip List)

菜鸟: 老鸟&#xff0c;我最近在处理一个数据操作的时候遇到了性能问题。我在一个有序数组中查找元素&#xff0c;发现查找速度有点慢&#xff0c;尤其是数据量大的时候。你有什么好的建议吗&#xff1f; 老鸟: 这是个好问题&#xff0c;有许多数据结构可以优化查找操作。你听…

Python爱心射线(完整代码)

目录 系列目录 写在前面​ 完整代码 下载代码 代码分析 写在后面 系列目录 序号直达链接表白系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3

人工智能领域各方向顶级会议和期刊

会议 人工智能基础与综合&#xff1a;AAAI、CICAI (!)、UAI、IJCAI 机器学习&#xff1a;COLT、ICLR、ICML、NeurIPS 模式识别与计算机视觉&#xff1a;ECCV、CVPR、ICCV 语言与语音处理&#xff1a;ACL、EMNLP 知识工程与数据挖掘&#xff1a;SIGKDD、SIGMOD、ICDE、SIGIR、V…

web知识

sql注入的万能密码:1’ or true#如果页面没有什么东西可见&#xff0c;首先可以用diresearch看看有没有什么隐藏的目录&#xff0c;或者检查源代码&#xff0c;如果这些都没成功可以用 dirsearch如果没有找到东西&#xff0c;可能需要调低线程 dirsearch.py -u url -e * --ti…

【60天备战软考高级系统架构设计师——第十五天:项目管理——风险管理】

风险管理是项目成功的重要保障&#xff0c;通过有效的风险识别、评估和应对&#xff0c;确保项目能够顺利推进。 学习内容&#xff1a; 风险识别 学习内容&#xff1a;识别项目中的潜在风险&#xff0c;包括技术风险、管理风险、市场风险等。了解常用的风险识别工具和技术&…

语音转文字工具全解析

无论是学生群体记录课堂笔记&#xff0c;职场人士整理会议纪要&#xff0c;还是自媒体创作者捕捉灵感火花&#xff0c;录音转文字软件都以其独特的便利性和高效性赢得了广泛的好评。今天&#xff0c;就让我们一起探索那些深受大家喜爱的录音转文字工具吧。 1.365在线转文字 链…

【Python】由二维列表初始化导致修改元素时会修改相同位置元素的引用问题f = [[0] * len(matrix[0])] * len(matrix)

背景&#xff1a; 在刷Leetcode过程中&#xff0c;需要初始化一个与另一个矩阵&#xff08;如 matrix&#xff09;尺寸相同的二维列表&#xff08;如 f&#xff09;&#xff0c;并填充初始值&#xff08;如 0&#xff09;。一开始用的是这种方法试图创建一个所有元素均为 0 的…

django自用教程

编程软件: pycharm django介绍:django是Pythonweb的一个框架&#xff0c;是用来构建网站的工具。 要想使用django&#xff0c;首先需要下载django模块&#xff0c;通过使用以下代码实现: pip install django 安装完成后&#xff0c;在django的目录下有一个文件django-admin&am…

docker基础知识-docker0网桥

文章目录 示意图Docker 网桥的工作原理Docker 网桥的优势Docker 网桥的局限性自定义网桥网络 Docker 网桥&#xff08;Docker bridge network&#xff09;是 Docker 默认的一种网络模式&#xff0c;它允许 Docker 容器之间通过一个虚拟的交换机进行通信。Docker 网桥网络为容器…

Linux shell编程学习笔记79:cpio命令——文件和目录归档工具(下)

在 Linux shell编程学习笔记78&#xff1a;cpio命令——文件和目录归档工具&#xff08;上&#xff09;-CSDN博客https://blog.csdn.net/Purpleendurer/article/details/142095476?spm1001.2014.3001.5501中&#xff0c;我们研究了 cpio命令 的功能、格式、选项说明 以及 cpi…

计算机视觉的应用32-基于Swin Transformer模型的嵌入混合注意力机制的人脸表情识别的应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用32-基于Swin Transformer模型的嵌入混合注意力机制的人脸表情识别的应用。随着深度学习技术的不断演进&#xff0c;计算机视觉领域迎来了诸多变革&#xff0c;其中 Transformer 架构的引入&#xf…

verilog vscode 与AI 插件

Verilog 轻量化开发环境 背景 笔者常用的开发环境 VIAVDO, 体积巨大&#xff0c;自带编辑器除了linting 能用&#xff0c;编辑器几乎不能用&#xff0c;仿真界面很友好&#xff0c;但是速度比较慢。Sublime Text, 非常好用的编辑器&#xff0c;各种插件使用verilog 非常方便…

sqlite在Windows环境下安装、使用、node.js连接

sqlite在Windows环境下安装、使用、node.js连接 前言&#xff1a;2024年9月10日 1. 下载安装 sqlite 的安装非常简单 去官网下载对应压缩包 将两个压缩包解压&#xff0c;并将解压出来的文件放在同一目录下 将上面的目录路径配置到环境变量 path 中 2. 执行 sql sqlite …

解锁Android开发利器:MVVM架构_android的mvvm

// 从网络或其他数据源获取天气数据return Weather(city, "25C") }} 2.定义View&#xff1a;class WeatherActivity : AppCompatActivity() { private lateinit var viewModel: WeatherViewModel override fun onCreate(savedInstanceState: Bundle?) {super.onCre…