JVM 锁优化和逃逸分析详解

1 锁优化

JVM 在加锁的过程中,会采用自旋、自适应、锁消除、锁粗化等优化手段来提升代码执行效率。

1.1 自旋锁和自适应自旋

现在大多的处理器都是多核处理器 ,如果在多核心处理器,有让两个或者以上的线程并行执行,我们可以让一个等待线程不放弃处理器的执行时间。设置一个等待超时时间,看线程是否能够很快的释放锁,在等等待的这段时间可以执行一个空循环,让当前线程继续占用 CPU 的时间片。这就是所谓的「自旋锁」。

JVM 中可以通过 +XX:UseSpinning来开启自旋锁,在 JDK1.6 过后默认为我们开启。由于自旋锁的使用会让锁的竞争者占用更多的处理器时间, JVM 规定了一个自旋次数的一个参数。我们可以通过 -XX:PreBlockSping来进行更改(默认10次)。

偏向锁、轻量级锁的状态转化及对象 Mark Word 的关系转换入下图所示:

751bde54ba26d643ee98f1712fc0b9d9.png
偏向锁、轻量级锁的状态转化及对象 Mark Word 的关系


1.2 锁消除

锁消除是指虚拟机即时编译器在运行时检测到某段需要同步的代码不可能存在共享数据竞争而实施的一种对锁进行消除的优化策略。锁消除的主要判断依据于逃逸分析。如果判断一段代码,在堆上所有的数据都不会逃逸出去被别的线程访问到,那就把它当作栈上的数据对待,认为它们是私有的,同步加锁就无需进行。

下面是三个字符串 x, y, z 相加的例子,无论是从源代码上还是逻辑上都没有进行同步:

public String concatStr(String x, String y, String z) {return  x + y + z;
}

String 是一个不可变的类,对字符的链接总是生成新的 String 对象来进行的,因此 Javac 编译器会对 String 链接进行自动优化,在 JDK5 之前字符串链接会转换为 StringBuffer;在 JDK5 之后会转换为 StringBuilder 对象连续的 append()操作,我们看看 javac 过后,反编译的结果:

public String concatStr(String x, String y, String z) {StringBuilder sb = new StringBuilder();sb.append(x);sb.append(y);sb.append(z);return  sb.toString();
}

我们再来看看 javap 反编译的结果:

c93945c8259a73b04ca4fc76e9f4b38b.png
javap 反编译的结果

这里大家可能会担心 StringBuilder 不是线程安全的的操作会存在线程安全的问题吗?这里的答案是不会,x + y + z 操作的优化「经过逃逸分析」过后,他的动态作用域被限制在了 concatStr方法内,就是说当前实际执行的 StringBuilder 的操作在 concatStr 方法内部,「其他的外部线程无法访问」到,所以这里「虽然有锁,但是可以被安全的消除掉。所以当我们进行编译过后,这段代码就会忽略掉所有的同步措施直接执行。」

1.3 锁粗化

原则上,我们在写代码的时候,总是推荐将同步块的作用范围限制得尽可能的小--只在共享数据的实际操作作用域中才进行同步,这样也是为了使得需要同步的操作尽可能的变少,即使存在锁的竞争,等待的锁的线程也能很快的获取到锁。大多数情况下,上面的原则都是正确的,但是如果「一系列的连续操作都是对同一个对象反复加锁和解锁,甚至加锁操作时出现在循环体之中」的,那即使没有线程的竞争,频繁的进行相互操作也会导致不必需要的性能损耗。

StringBuffer buffer = new StringBuffer();
/**  锁粗化 */ 
public void append(){buffer.append("aaa").append(" bbb").append(" ccc"); 
}

上面的代码每次调用 buffer.append 方法都需要加锁和解锁,如果 JVM 家册到有一串连续的对同一个对象加锁和解锁的操作,就会将其合并成一次范围更大的加锁解锁操作,即在第一个 append 方法执行的时候进行加锁,最后一个 append 方法结束后进行解锁。

2 逃逸分析

逃逸分析(Escape Analysis),是一种可能减少有效 Java 程序中同步负载和内存堆分配压力的跨全局函数数据流分析算法。通过逃逸分析, Java Hotspot 编译器能够分析出一个新的对象引用范围从而决定是否要将这个对象分配到堆上,「逃逸分析的基本行为就是分析对象的动态作用域。」

2.1 方法逃逸

当一个对象在方法里面被定义后,它可能被外部方法所引用,例如调用参数传递到其他方法中,这种称为方法逃逸。

2.2 线程逃逸

当一个对象可能被外部线程访问到,比如:赋值给其他线程中访问的实例变量,这种称为线程逃逸。

2.3 通过逃逸分析,编译器对代码的优化

如果能够证明一个对象不会逃逸到到方法外或线程外(其他线程方法或者线程无法通过任何方法访问该变量),或者逃逸程度比较低(只逃逸出方法而不逃逸出线程)则可以对这个对象采用不同程度的优化:

  1. 栈上分配(Stack Allocations)完全不会逃逸的局部变量和不会逃逸出线程的对象,采用栈上分配,对象就会跟随方法的结束自动销毁。以减少垃圾回收器的压力。

  2. 标量替换(Scalar Replacement)有个对象可能不需要作为一个连续的存储结果存储也能被访问到,那么对象的部分(或者全部)可以不存储在内存,而是存储在 CPU 寄存器中。

  3. 同步消除(Synchronization Elimination)如果一个对象发现只能在一个线程访问到,那么这个对象的操作可以考虑不同步。

参考资料

  • https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html

  • https://www.cnblogs.com/xidongyu/p/10891303.html

  • https://www.cnblogs.com/kkkkkk/p/5543799.html

转自:心城以北,

链接:juejin.cn/post/7055891706826194975

------

我们创建了一个高质量的技术交流群,与优秀的人在一起,自己也会优秀起来,赶紧点击加群,享受一起成长的快乐。另外,如果你最近想跳槽的话,年前我花了2周时间收集了一波大厂面经,节后准备跳槽的可以点击这里领取!

推荐阅读

  • 复旦发布中国版 ChatGPT :MOSS

  • Javalin:一个轻量的 Web Framework

  • 40岁还在做程序员是好还是坏?

··································

你好,我是程序猿DD,10年开发老司机、阿里云MVP、腾讯云TVP、出过书创过业、国企4年互联网6年。从普通开发到架构师、再到合伙人。一路过来,给我最深的感受就是一定要不断学习并关注前沿。只要你能坚持下来,多思考、少抱怨、勤动手,就很容易实现弯道超车!所以,不要问我现在干什么是否来得及。如果你看好一个事情,一定是坚持了才能看到希望,而不是看到希望才去坚持。相信我,只要坚持下来,你一定比现在更好!如果你还没什么方向,可以先关注我,这里会经常分享一些前沿资讯,帮你积累弯道超车的资本。

点击领取2023最新10000T学习资料

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

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

相关文章

kubernetes学习之路--BadPods(Part1)

摘要:对Pod配置进行实战学习,以BadPods项目为例学习危险配置。 目录 一.BadPods介绍及使用 二.BadPods配置学习 2.1 less1--Everything allowed 基本操作学习 2.2 less1--Everything allowed 渗透学习 一.BadPods介绍及使用 项目地址:h…

基于GPT3.5实现本地知识库解决方案-利用向量数据库和GPT向量接口-实现智能回复并限制ChatGPT回答的范围...

标题有点长,但是基本也说明出了这篇文章的主旨,那就是利用GPT AI智能回答自己设置好的问题 既能实现自己的AI知识库机器人,又能节省ChatGPT调用的token成本费用。 代码仓库地址 document.ai: 基于GPT3.5的通用本地知识库解决方案 下面图片是整…

英语语法大全

文章目录 一、主语1、名词、代词和动词做主语2、主语从句做主语,谓语动词用单数3、主语从句练习 二、谓语动词1、谓语动词种类2、主谓一致 三、宾语1、单宾语2、双宾语3、复合宾语4、宾语从句 四、定语1、定语从句2、定语从句的翻译 五、状语1、分词做状语2、独立主…

规模效应和网络效应

前几天小米造车、华为造车、大疆造车、滴滴造车、百度造车集中PR。群中讨论智能新能源汽车的未来集中。甚至延伸讨论到了:云计算的未来集中度、SaaS的未来集中度。怎么能提高行业集中度,是我们都在苦苦思考的。 于是就讨论到两个词:规模效应、…

真*加班狗聚众舔福豹《打工人的那些事》

真*加班狗聚众舔福豹《打工人的那些事》 文章目录 近日的杭州金钱豹外逃新闻,相信大家都听说了。 没看过的也不急,我在这里帮大家简单理一理。 根据杭州市富阳区8日官方发布,5月7日20时许,群众报警称在富阳区银湖街道受降四联村…

国内“风口”转变,中国游戏公司纷纷“外逃”,东南亚是个好去处

中国游戏开发商正在加强对国际市场,特别是东南亚市场的承诺,因为他们的国内公司正在努力应对更困难的中国市场,以便实施在下一阶段发展布局。 根据移动应用市场情报公司Sensor Tower的一份报告,按收入排名的前100名全球移动游戏中…

chatgpt赋能python:Python编译成库的利与弊

Python编译成库的利与弊 Python作为一种高级编程语言,具有简洁易读的语法和强大的生态系统,在数据科学、Web开发、游戏开发等领域得到广泛应用。然而,Python解释器的执行效率较低,因此为了提高Python程序的性能,常使用…

产业大模型刚开卷,京东跑进“最后半公里”

点击关注 文|姚 悦 编|王一粟 “京东一直在探索哪些产品、技术、场景可以真正把大模型用起来,在我们内部的场景中反复验证后,才决定在7月份对外发布,现在我们在零售、健康、物流、金融等业务场景里已经积累了一些经…

赠书 | 写作、绘画、游戏、音视频编辑…AIGC为内容生产带来了什么?

文中有数据派THU福利哦 当AIGC产品不断涌向社会,人们纷纷认为美图app“危了“的时候,美图公司创始人兼首席执行官吴欣鸿表示,影像和 AIGC 的创新结合,将带来影像生产力的大爆发,同时会为相关领域带来新的职业和新的创业…

中文公开聊天语料库

源 / 专知 语料内容 该库搜集了包含chatterbot、豆瓣多轮、PTT八卦语料、青云语料、电视剧对白语料、贴吧论坛回帖语料、微博语料小黄鸡语料共8个公开闲聊常用语料和短信,并对其进行了统一化规整和处理,达到直接可以粗略使用的目的。 使用方法 语料下载&…

获得文本语料和词汇资源(基于nltk)

在自然语言处理的实际项目中,通常要使用大量的语言数据或者语料库。本章的目的是要回答下列问题: 什么是有用的文本语料和词汇资源,我们如何使用 Python 获取它们?哪些 Python 结构最适合这项工作?编写 Python 代码时…

NLP领域中文对话系统数据集总结(有下载地址)

一、豆瓣多轮对话数据集 1、简介: 测试数据包含 1000 个对话上下文,对于每个上下文,创建 10 个响应作为候选。正确的响应意味着响应可以自然地回复给定上下文的消息。每对收到三个标签,大多数标签被视为最终决定。 2、数据格式&…

肠道病毒组识别早产儿坏死性小肠结肠炎发病前的特异性病毒特征

期刊:Nature microbiology 影响因子:30.964 发表时间:2022 样本类型:粪便样本 研究背景 坏死性小肠结肠炎(NEC)是早产的严重后果,通常与肠道细菌微生物群的改变有关。然…

新型病毒来了【PcaPatchDbTask】

急报!!新型病毒来了【PcaPatchDbTask】 1.什么是PcaPatchDbTask PcaPatchDbTask是一种新型的木马 2.PcaPatchDbTask的危害 【1】他会劫持你的浏览器主页 【2】他会读取你的键盘信息 【3】他会获取你电脑的联系人菜单 【4】它甚至不会被安全软件查杀 3.…

Nature Reviews:给医生的菌群分析指南(下)

本文转载自“态昌基因”,己获授权。 Nature Reviews:给医生的菌群分析指南(上),主要从实验阶段介绍了以下7方面,不清楚的请点击链接跳转原文阅读。 1. 样本选择 2. 样本的采集 3. 样本的保存与保护剂 4. DNA提取 5.我到…

关于儿童急性感染性腹泻

腹泻是一种常见的症状,可导致儿童生长发育迟滞和营养不良。根据世界卫生组织(WHO)发布的数据显示,急性腹泻在5岁以下儿童死亡原因中排第二位,仅次于肺炎。引起儿童腹泻的原因包括感染和非感染因素,后者主要…

MPO抗体对丨CalBioreagents 中英文说明书

艾美捷CalBioreagents MPO抗体对英文参数说明: CATALOG NUMBER: M684 PRODUCT DESCRIPTION: Mouse Monoclonal anti-human Insulin IMMUNOGEN: Purified human MPO IMMUNOGLOBULIN ISOTYPE: IgG1 PURIFICATION: Purified by DEAE chromatography. BUFFER: Sup…

PICRUSt2菌群功能预测分析

生科云网址:https://www.bioincloud.tech 01 课程简介 PICRUSt2的原理是基于已测微生物基因组的序列,推断它们的共同祖先的基因功能谱,对数据库中其它未测物种(基因组未知)的基因功能谱进行推断,构建微生物…

病毒组学数据分析 -03 CheckV病毒序列识别

CheckV 是一个完全自动化的命令行管道,用于评估单重叠群病毒基因组的质量,包括识别集成原病毒的宿主污染、估计基因组片段的完整性以及识别封闭基因组。 管道可以分为4个主要步骤:A:去除原噬菌体上的宿主污染 根据与自定义 HMM 数…

新冠病毒分型和突变分析(SARS-CoV2_ARTIC_Illumina)

SARS-CoV2_ARTIC_Illumina新冠病毒分型和突变分析 一. 本文适用于使用Artic扩增子扩增,Illumina双端测序,用于分析新冠病毒突变及分型鉴定 二. 概览:按照惯例,先上一张概览图 流程输入SRR22216743_1.fastq.gz SRR22216743_2.fas…