java idle 机制_HotSpot VM重量级锁降级机制的实现原理
HotSpot VM内置锁的同步机制简述:
HotSpot VM采用三中不同的方式实现了对象监视器——Object Monitor,并且可以在这三种实现方式中自动切换。偏向锁通过在Java对象的对象头markOop中install一个JavaThread指针的方式实现了这个Java对象对此Java线程的偏向,并且只有该偏向线程能够锁定Lock该对象。但是只要有第二个Java线程企图锁定这个已被偏向的对象时,偏向锁就不再满足这种情况了,然后呢JVM就将Biased Locking切换成了Basic Locking(基本对象锁)。Basic Locking使用CAS操作确保多个Java线程在此对象锁上互斥执行。如果CAS由于竞争而失败(第二个Java线程试图锁定一个正在被其他Java线程持有的对象),这时基本对象锁因为不再满足需要从而JVM会切换到膨胀锁 - ObjectMonitor。不像偏向锁和基本对象锁的实现,重量级锁的实现需要在Native的Heap空间中分配内存,然后指向该空间的内存指针会被装载到Java对象中去。这个过程我们称之为锁膨胀。
降级的目的和过程:
因为BasicLocking的实现优先于重量级锁的使用,JVM会尝试在SWT的停顿中对处于“空闲(idle)”状态的重量级锁进行降级(deflate)。这个降级过程是如何实现的呢?我们知道在STW时,所有的Java线程都会暂停在“安全点(SafePoint)”,此时VMThread通过对所有Monitor的遍历,或者通过对所有依赖于MonitorInUseLists值的当前正在“使用”中的Monitor子序列进行遍历,从而得到哪些未被使用的“Monitor”作为降级对象。
可以降级的Monitor对象:
重量级锁的降级发生于STW阶段,降级对象就是那些仅仅能被VMThread访问而没有其他JavaThread访问的Monitor对象。
HotSpot VM中的实现:
上述降级过程在HotSpot VM中的实现,可以参考:
void ObjectSynchronizer::deflate_idle_monitors() {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
int nInuse = 0 ; // currently associated with objects int nInCirculation = 0 ; // extant int nScavenged = 0 ; // reclaimed bool deflated = false;
ObjectMonitor * FreeHead = NULL ; // Local SLL of scavenged monitors ObjectMonitor * FreeTail = NULL ;
TEVENT (deflate_idle_monitors) ;
// Prevent omFlush from changing mids in Thread dtor's during deflation// And in case the vm thread is acquiring a lock during a safepoint// See e.g. 6320749 Thread::muxAcquire (&ListLock, "scavenge - return") ;
if (MonitorInUseLists) {
int inUse = 0;
for (JavaThread* cur = Threads::first(); cur != NULL; cur = cur->next()) {
nInCirculation+= cur->omInUseCount;
int deflatedcount = walk_monitor_list(cur->omInUseList_addr(), &FreeHead, &FreeTail);
cur->omInUseCount-= deflatedcount;
// verifyInUse(cur); nScavenged += deflatedcount;
nInuse += cur->omInUseCount;
}
// For moribund threads, scan gOmInUseList if (gOmInUseList) {
nInCirculation += gOmInUseCount;
int deflatedcount = walk_monitor_list((ObjectMonitor **)&gOmInUseList, &FreeHead, &FreeTail);
gOmInUseCount-= deflatedcount;
nScavenged += deflatedcount;
nInuse += gOmInUseCount;
}
} else for (ObjectMonitor* block = gBlockList; block != NULL; block = next(block)) {
// Iterate over all extant monitors - Scavenge all idle monitors. assert(block->object() == CHAINMARKER, "must be a block header");
nInCirculation += _BLOCKSIZE ;
for (int i = 1 ; i < _BLOCKSIZE; i++) {
ObjectMonitor* mid = &block[i];
oop obj = (oop) mid->object();
if (obj == NULL) {
// The monitor is not associated with an object.// The monitor should either be a thread-specific private// free list or the global free list.// obj == NULL IMPLIES mid->is_busy() == 0 guarantee (!mid->is_busy(), "invariant") ;
continue ;
}
deflated = deflate_monitor(mid, obj, &FreeHead, &FreeTail);
if (deflated) {
mid->FreeNext = NULL ;
nScavenged ++ ;
} else {
nInuse ++;
}
}
}
MonitorFreeCount += nScavenged;
// Consider: audit gFreeList to ensure that MonitorFreeCount and list agree.
if (ObjectMonitor::Knob_Verbose) {
::printf ("Deflate: InCirc=%d InUse=%d Scavenged=%d ForceMonitorScavenge=%d : pop=%d free=%d\n",
nInCirculation, nInuse, nScavenged, ForceMonitorScavenge,
MonitorPopulation, MonitorFreeCount) ;
::fflush(stdout) ;
}
ForceMonitorScavenge = 0; // Reset
// Move the scavenged monitors back to the global free list. if (FreeHead != NULL) {
guarantee (FreeTail != NULL && nScavenged > 0, "invariant") ;
assert (FreeTail->FreeNext == NULL, "invariant") ;
// constant-time list splice - prepend scavenged segment to gFreeList FreeTail->FreeNext = gFreeList ;
gFreeList = FreeHead ;
}
Thread::muxRelease (&ListLock) ;
if (ObjectMonitor::_sync_Deflations != NULL) ObjectMonitor::_sync_Deflations->inc(nScavenged) ;
if (ObjectMonitor::_sync_MonExtant != NULL) ObjectMonitor::_sync_MonExtant ->set_value(nInCirculation);
// TODO: Add objectMonitor leak detection.// Audit/inventory the objectMonitors -- make sure they're all accounted for. GVars.stwRandom = os::random() ;
GVars.stwCycle ++ ;
}
补充说明:JEP - Concurrent Monitor Deflation,旨在通过并发手段解决重量级锁降级过程中的效率问题,可以参考:JEP draft: Concurrent Monitor Deflation 。
java idle 机制_HotSpot VM重量级锁降级机制的实现原理相关推荐
- java 锁降级 知乎_HotSpot VM重量级锁降级机制的实现原理
HotSpot VM内置锁的同步机制简述: HotSpot VM采用三中不同的方式实现了对象监视器--Object Monitor,并且可以在这三种实现方式中自动切换.偏向锁通过在Java对象的对象头 ...
- 偏向锁,轻量级锁,重量级锁(java)
轻量级锁是JDK 1.6之中加入的新型锁机制,它名字中的"轻量级"是相对于使用操作系统互斥量来实现的传统锁而言的,因此传统的锁机制就称为"重量级"锁.首先需要强 ...
- (JUC)图文并茂!!!! 超详细 偏向锁VS轻量级锁VS重量级锁VS自旋
偏向锁,轻量级锁,重量级锁 前言 java对象内存布局 (1)重量级锁(Moniter) (2)轻量级锁 锁膨胀.自旋.自适应自旋 (3)偏向锁(以64位虚拟机为例) 2.偏向锁撤销的3种情况 (1) ...
- 锁升级过程(无锁、偏向锁、轻量级锁、重量级锁)
文章目录 Synchronized锁升级的背景 Synchronized的性能变化 Java5之前,用户态和内核态之间的切换 为什么每个对象都可以称为一把锁? Java6开始优化Synchronize ...
- 锁,CAS,Synchronized 原理
作者:~小明学编程 文章专栏:JavaEE 格言:热爱编程的,终将被编程所厚爱. 目录 常见的锁 悲观锁与乐观锁 悲观锁 乐观锁 读写锁 重量级锁 vs 轻量级锁 挂起等待锁和自旋锁 公平锁和非公平锁 ...
- java 重量级锁_轻量级锁和重量级锁的区别分别有哪些?java锁机制教程
Java中有着各种锁机制,今天我们要说的就是其中两种状态,轻量级锁与重量级锁,小伙伴们知道它们的区别分别有哪些吗?下面来了解一下吧. 首先我们了解一下有哪些锁状态吧 锁的状态总共有四种:无锁状态.偏向 ...
- 【Java 并发编程】线程锁机制 ( 锁的四种状态 | 无锁状态 | 偏向锁 | 轻量级锁 | 重量级锁 | 锁竞争 | 锁升级 )
文章目录 一.悲观锁示例 ( ReentrantLock ) 二.重量级锁弊端 三.锁的四种状态 ( 无锁状态 | 偏向锁 | 轻量级锁 | 重量级锁 ) 四.锁的四种状态之间的转换 ( 无锁状态 - ...
- 【Java 并发编程】线程锁机制 ( 线程安全 | 锁机制 | 类锁 | 对象锁 | 轻量级锁 | 重量级锁 )
文章目录 一.线程安全 二.锁机制 ( 类锁 | 对象锁 ) 三.锁分类 ( 轻量级锁 | 重量级锁 ) 一.线程安全 多个线程同时访问 同一个共享变量 时 , 只要能保证 数据一致性 , 那么该变量 ...
- Java中的锁机制 -- 乐观锁、悲观锁、自旋锁、可重入锁、读写锁、公平锁、非公平锁、共享锁、独占锁、重量级锁、轻量级锁、偏向锁、分段锁、互斥锁、同步锁、死锁、锁粗化、锁消除
文章目录 1. Java中的锁机制 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 可重入锁(递归锁) 1.5 读写锁 1.6 公平锁 1.7 非公平锁 1.8 共享锁 1.9 独占锁 1.1 ...
最新文章
- excel操作技巧记录(实时更新)
- php禁止某个链接,php – 使用htaccess忽略链接的某些部分
- java并发Exchanger的使用
- webRTC——浏览器里的音视频通话 1
- c语言配电自动化,我是电气工程及其自动化专业的要学C语言吗?
- C++ 通讯录设计(二)
- 互联网运营遇到瓶颈?这套数据运营体系,高手和小白都必看
- zplane函数怎么用m文件调用_matlab中cla用法
- 关于Unity中的transform组件(二)
- 美国科技股昨日普遍下跌:华尔街受特朗普影响抛售科技股票
- Pyspark:NLP(文本分类)
- linux终端安装deb文件,如何通过命令行安装.deb文件?
- meta标签http-equiv属性实现自动刷新页面和重定向
- 2018计算机考研时间表,2018年考研时间与考试各科目的日程安排
- cocoapods的安装
- 高通骁龙820A凭什么能赢得众多车厂的芳心
- 数值模拟偏微分方程的三种方法介绍
- IBM放弃SoftLayer品牌 将其归入Bluemix之中
- 超低功耗 段码LCD液晶显示驱动IC-VKL060 SSOP24 15SEG*4COM,超低工作电流约7.5微安,多用于传感器/水电表/工控仪表等
- 汽车动力性matlab程序,汽车动力性计算matlab程序
热门文章
- 将dll制作成控件_全国首例将“影视作品”制作成“网络图片集”方式侵权案宣判...
- okhttp 工具类_日语学习工具推荐,小白必备!
- domino流程图_OA实施工程师一线解读Java与Domino优劣
- docker mysql配置 丢失_Ubuntu16.04服务器环境配置 – Docker、MySQL、Redis
- 忽视大小写函数_使用率低但功能强大的6个Excel函数公式应用技巧解读!
- Chrome用户不喜新版:宁用其他浏览器也不要用旧版本
- ECharts 仪表盘的轴线宽度修改
- linux下opencv读取图片并存储到mysql数据库中
- java基础学习笔记(三)
- 我的世界服务器修改末地难度,涨姿势啦!我的世界老司机带你解锁进入末地的高难度姿势!...