Safepoints: Meaning, Side Effects and Overheads(译文)
Safepoints: Meaning, Side Effects and Overheads (安全点:含义、副作用和开销)
什么是安全点?
最近有人问我:“安全点就像安全的词吗?” 简短的答案是“不是真的”,但是由于我喜欢这个比喻,因此我将其与之对应:想象一下,如果您将有一个充满了所有线程的JVM,这些线程都忙,费力,正在改变堆。 其中一些具有<gasp>共享的可变状态。 他们像动物一样,同时改变彼此的状态。有些人站在角落改变自己的状态(他们会失明)。突然,一个霓虹灯闪烁着(菠萝)PINEAPPLES一词。变异者一个接一个地停止了它们猖獗的 堆 堆放,等着汗水淋漓。当最后一个变种人停下来时,一群精灵进来,倒空烟灰缸,装满所有饮料,拖走水坑,然后尽快消失到北极。 该标志已关闭,线程返回到它。<内部对话>太多了吗? 这里的阴影就像35c,所以出汗就像...不? 没关系</ 内部对话>
在网上可以找到很多关于Safepoints的参考,这里是我对更细致的使用/定义的尝试,从现在开始,没有汗水的变异者。
- 安全点是对执行线程的状态有充分描述的执行范围(A safepoint is a range of execution where the state of the executing thread is well described. )。 变异器线程是操纵JVM堆的线程(您所有的Java线程都是变异器。非Java线程在调用与堆进行交互的JVM API时也可以被视为变异器)。
- 在安全点上,变异器线程在与堆的交互中处于已知且定义明确的位置。这意味着堆栈上的所有引用都已映射(在已知位置),并且JVM可以account for所有引用。只要线程保持在安全点,我们就可以安全地操作堆+堆栈,以使线程在离开安全点时对世界的看法保持一致。
当JVM由于GC或许多其他原因之一而希望检查或更改堆时,这特别有用。如果无法解释堆栈上的引用,并且JVM要运行GC,则可能会遗漏某些对象仍处于活动状态(从堆栈中引用)并收集它们的事实,或者它可能移动某些对象而不更新堆栈上的引用 导致内存损坏。
这是部分活动列表,只有所有变种线程都处于安全点时,JVM才运行这些活动,并且只有在释放后才能离开(在全局安全点处),这些活动有时称为安全点操作:
- Some GC phases (the Stop The World kind) (phases--阶段)
- JVMTI stack sampling methods (not always a global safepoint operation for Zing))
- Class redefinition
- Heap dumping
- Monitor deflation (not a global safepoint operation for Zing)
- Lock unbiasing
- Method deoptimization (not always)
- And many more!
Azul自己的JavaOne 2014的John Cuthbertson的一篇精彩演讲谈到了安全点的背景知识,并分配了有关GC以外的安全点操作的详细信息(我们在Azul认为GC是一个已解决的问题,所以谈话进入了停止的其余原因)。
请注意,仅在某些JVM实现中才存在请求全局安全点和线程安全点之间的区别(例如Zing,Azul Systems JVM。提醒:我为Azul工作)。 重要的是,它在OpenJDK / Oracle JVM上不存在。 这意味着Zing可以将单个线程带到安全点。
总结一下:
- 安全点是常见的JVM实现细节
- 它们用于使变异线程处于暂停状态,而JVM则“修复了东西”
- 在OpenJDK / Oracle上,每个安全点操作都需要一个全局安全点
- 当前所有的JVM对全局安全点都有一些要求
我的线程什么时候处于安全点?
因此,将线程置于安全点可以使JVM继续进行托管运行时魔术表演,太棒了!这种古怪的状态何时发生?
- 如果Java线程在锁或同步块上阻塞,在监视器上等待,驻留或在阻塞IO上阻塞,则它在安全点上。本质上,所有这些都可以作为Java线程的有序调度事件,也可以作为在线程被置于安全点之前搁置的整理工作的一部分。
- 执行JNI代码时,Java线程处于安全点。 在越过本机调用边界之前,将堆栈保持一致状态,然后再移交给本机代码。 这意味着线程仍可以在安全点运行。
- 正在执行字节码的Java线程不在安全点上(或至少JVM无法假定它在安全点上)。
- 在调度之前,未在安全点中断(由操作系统)的Java线程不会被带到安全点。
JVM和正在运行的Java线程在安全点之间具有以下关系:
- JVM无法强制任何线程进入安全点状态。
- JVM可以阻止线程离开安全点状态。
那么,JVM如何使所有线程进入安全点状态? 问题在于将线程挂起在已知状态,而不仅仅是中断它。为了实现此目标,JVM使Java线程在观察到“安全点标志”的情况下将其自身挂在方便的位置。
将Java线程带到安全点
Java线程以“合理”的时间间隔轮询“安全点标志”(全局或线程级别),并在观察到“转到安全点”标志时转换为安全点状态(线程在安全点被阻塞)。这很简单,但是由于我们不想花费所有时间检查是否需要停止C1 / C2编译器(-client / -server JIT编译器),因此请尽量减少安全点轮询。除了标志检查本身的成本之外,保持“已知状态”会为某些优化的实现增加极大的复杂性,因此,将安全点保持更远的距离将为优化提供更大的范围。这些考虑因素共同导致安全点民意调查的位置如下:
- 在解释器中运行时,在任意两个字节码之间(有效)
- 在C1 / C2编译代码中的“非计数”循环后沿 ( On 'non-counted' loop back edge in C1/C2 compiled code )
- A common type of program loop is one that is controlled by an integer that counts up from a initial value to an upper limit. Such a loop is called a counting loop. The integer is called a loop control variable. Loops are implemented with the conditional branch, jump, and conditional set instructions.
- C1 / C2编译代码中的方法进入/退出(Zing进入,OpenJDK退出)。 请注意,内联方法时,编译器将删除这些安全点轮询。
------------------------------------------------------------------------------------------------------------
补充JIT:
JIT 是 just in time 的缩写, 也就是即时编译编译器。使用即时编译器技术,能够加速 Java 程序的执行速度。下面,就对该编译器技术做个简单的讲解。
当 JVM 执行代码时,它并不立即开始编译代码。这主要有两个原因:
首先,如果这段代码本身在将来只会被执行一次,那么从本质上看,编译就是在浪费精力。因为将代码翻译成 java 字节码相对于编译(编译成二进制)这段代码并执行代码来说,要快很多。
当然,如果一段代码频繁的调用方法,或是一个循环,也就是这段代码被多次执行,那么编译就非常值得了。因此,编译器具有的这种权衡能力会首先执行解释后的代码,然后再去分辨哪些方法会被频繁调用来保证其本身的编译。其实说简单点,就是 JIT 在起作用,我们知道,对于 Java 代码,刚开始都是被编译器编译成字节码文件,然后字节码文件会被交由 JVM 解释执行,所以可以说 Java 本身是一种半编译半解释执行的语言。Hot Spot VM 采用了 JIT compile 技术,将运行频率很高的字节码直接编译为机器指令执行以提高性能,所以当字节码被 JIT 编译为机器码的时候,要说它是编译执行的也可以。也就是说,运行时,部分代码可能由 JIT 翻译为目标机器指令(以 method 为翻译单位,还会保存起来,第二次执行就不用翻译了)直接执行。
JIT 编译器在运行程序时有两种编译模式可以选择,并且其会在运行时决定使用哪一种以达到最优性能。这两种编译模式的命名源自于命令行参数(eg: -client 或者 -server)。JVM Server 模式与 client 模式启动,最主要的差别在于:-server 模式启动时,速度较慢,但是一旦运行起来后,性能将会有很大的提升。原因是:当虚拟机运行在-client 模式的时候,使用的是一个代号为 C1 的轻量级编译器,而-server 模式启动的虚拟机采用相对重量级代号为 C2 的编译器。C2 比 C1 编译器编译的相对彻底,服务起来之后,性能更高。
------------------------------------------------------------------------------------------------------------
Safepoints: Meaning, Side Effects and Overheads(译文)的更多相关文章
- JVM CPU Profiler技术原理及源码深度解析
研发人员在遇到线上报警或需要优化系统性能时,常常需要分析程序运行行为和性能瓶颈.Profiling技术是一种在应用运行时收集程序相关信息的动态分析手段,常用的JVM Profiler可以从多个方面对程 ...
- 转:概率主题模型简介 --- ---David M. Blei所写的《Introduction to Probabilistic Topic Models》的译文
概率主题模型简介 Introduction to Probabilistic Topic Models 转:http://www.cnblogs.com/siegfang/archive/2 ...
- Google C++单元测试框架GoogleTest---AdvancedGuide(译文)下
因为AdvancedGuide文档太长,分上下两部分,本文档接googletest--AdvancedGuide(译文)上:Google C++单元测试框架GoogleTest---AdvancedG ...
- Premiere Pro & After Effects插件开发调试方法
在给Adobe Premiere Pro(PR)和Adobe After Effects(AE)插件开发时,对于实时调试插件有着很强的需求.除了业务需求外,单步调试插件还能够摸清楚Plugin和Hos ...
- Google C++单元测试框架GoogleTest---AdvancedGuide(译文)上
本文是gtest高级测试指南的译文,由于文章太长,分上下两部分. 一.简介 本文档将向您展示更多的断言,以及如何构造复杂的失败消息,传播致命的故障,重用和加速您的测试夹具,并在您的测试使用各种标志. ...
- Java虚拟机 safepoints 初探
safepoint的定义很不规范,还跟JVM的具体实现有关,我们的讨论主要针对Hotspot VM. 先看看openjdk的官方解释: http://openjdk.java.net/groups/ ...
- 关于dvajs里effects的call和put
call会把return 传回来 put把参数穿回来了 在effects里好像只有yield能触发put ,call暂时没定
- 用AE (Adobe After Effects) 处理视频
这话要从年会说起,我们组的年会节目需要一段场外亲友团的评价视频,于是我们就靠在公司门口的logo前拍了这么一段.但是呢,有很多的不理想: 画面抖动 杂音好烦(中午吃饭时拍的,还有好大的微波炉好了的声音 ...
- Unity4升级Unity5后Image Effects问题
Assets\Editor\Image Effects\CameraMotionBlurEditor.js 会出现Ambiguous reference 'preview'错误提示,解决方法 查找pr ...
- Filter Effects - 使用 CSS3 滤镜处理图片
CSS3 Filter(滤镜)属性提供了提供模糊和改变元素颜色的功能.CSS3 Fitler 常用于调整图像的渲染.背景或边框显示效果.这里给大家分享的这个网站,大家可以体验下 CSS3 对图片的处理 ...
随机推荐
- java协程线程之虚拟线程
前言 众所周知,java 是没有协程线程的,在我们如此熟知的jdk 1.8时代,大佬们想出来的办法就是异步io,甚至用并行的stream流来实现,高并发也好,缩短事件处理时间也好:大家都在想着自己认为 ...
- Java并发工具CountDownLatch的使用和原理
1.等待多线程完成的 CountDownLatch CountDownLatch 允许一个或多个线程等待其他线程完成操作. 假如有这样一个需求:我们需要解析一个 Excel 里多个 sheet 的数据 ...
- Kubernets常用命令
查看所有namespace的pods运行情况 kubectl get pods --all-namespaces kubectl get service -ALL kubectl get deploy ...
- 01-jQuery的基本结构
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- QLabel标签快捷键的使用
1 from PyQt5.QtWidgets import * 2 import sys 3 4 class QlabelDemo(QDialog): 5 def __init__(self): 6 ...
- 小白也能搞定!Windows10上CUDA9.0+CUDNN7.0.5的完美安装教程
前言: 为什么要在本地电脑安装 CUDA,CUDA 是什么的,用来做什么?我想,点击标题进来的小伙伴,应该都清楚这些.不管你是用来做什么,或者跟我一样为了跑 Tensorflow 的 Object D ...
- CF1601 题解
偶然看这一场的题目,忽然很有感觉,于是写了一下 A 题面 考虑每一位可以单独分开考虑 考虑单独的一位,每次要选 \(m\) 个位置,可能产生贡献的位置就是这位为 1 的数,设数量为 \(x\),则 \ ...
- Cilium系列-13-启用XDP加速及Cilium性能调优总结
系列文章 Cilium 系列文章 前言 将 Kubernetes 的 CNI 从其他组件切换为 Cilium, 已经可以有效地提升网络的性能. 但是通过对 Cilium 不同模式的切换/功能的启用, ...
- 一文理解GIT的代码冲突
对于GIT,不知道有没有人和我一样,很长时间都是小心翼翼.紧张兮兮,生怕一不小心,自己辛苦写的代码没了. 特别是代码冲突,更是难到我无法理解,每次都要求助于百度,跟着人家的教程一步步解决,下一次还是这 ...
- Typescript - 索引签名
1 索引签名概述 在 TypeScript 中,索引签名是一种定义对象类型的方式,它允许我们使用字符串或数字作为索引来访问对象的属性. 1.1 索引签名的定义和作用 索引签名通过以下语法进行定义: { ...