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重量级锁降级机制的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在toad新增oracle用户,利用to
- 下一篇: mysql 数据库中数据去重,oracl