Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Locking and Synchronization第7回JVMソースコードリーディングの会         (OpenJDK)              中村 実      nminoru@nminoru.jp     nminoru197...
Javaのスレッド排他機構• Objectはすべて同期オブジェクトになれる – Critical section型の排他処理 – 再帰的なロックも可能• 文法 – synchronizedメソッド – Synchronized文    • バイ...
Java Synchronizationの問題点• 安易に書けるため使いすぎる – 不要な場所にもsynchronizedを書いてしまう。 – 衝突しないsynchronizationが異常に多い。 class Hoge {     int  ...
Java Synchronizationの実装方法• 基本(Biased Locking以前)  – -XX:-UseBiasedLocking• Biased Locking  – -XX:+UseBiasedLocking(OpenJDK6...
Hotspotのlock関係のオプション-XX:+UseBiasedLocking                     BiasedLockingを有効に。-XX:-TraceMonitorInflation                ...
基本ロック        6
基本ロックの方針• 衝突しないロック(uncontened lock)を効率  的に処理する• Phase1 (Lightweight) Locked  – Unlock状態のオブジェクトに最初のスレッド    がロックを行った状態。  – T...
ロックの構造体はどこにある?• oopの中にはない。• oopの第一ワードの_markは多目的用途で、  ロック時には切り替える(markOop.hpp)  _mark       hash code       age 0 01    Nor...
Phase 1• 最初のスレッドのロックはlocked状態へ遷移   – Interpreter frame上にBasicObjectLockを積むことでロックを表現   – 元の_markの内容を_displaced_headerへ退避   ...
Phase 1• 処理コード  InterpreterRuntime::monitorenter in interpreterRuntime.cpp:585    ObjectSynchronizer::fast_enter in synchr...
Phase2                                 ObjectMonitor    Object                                    _header            前にあった...
Phase2• 処理コード  – ObjectSynchronizer::inflate (inflation処理)  – ObjectMonitor::enter (inflation後のロック処理)• 複数のスレッドが同時にinflatio...
Biased Locking                 13
Biased Lockingのコンセプト• もっとCAS命令の削除を  – 基本ロックでは1回のロックで最低1回のCAS    命令を使う。• Biased Locking [Russell06]  – あるスレッドからロックされたオブジェクト...
Biased Lockingのコンセプト• どこにbiased threadを挿れるのか? – hash codeを潰す。        hash code     age 0 01    Normal(unlocked)     Thread...
Biased Lockingのコンセプト•   オブジェクト生成時はanonymously biased•   最初のスレッドがロックすると、そのスレッドのbiasがかかる(ここはCASが    必要)•   Biasedのかかったスレッドがロ...
Store-free biased locking(SFBL)BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, ...
Bulk rebiasing and revocation• Bulk rebiasing  – どのスレッドでbiasをかければいいのか時間    変化するので、一定周期でbiased toward given    threadをanony...
もっとCAS命令を減らしたい                 19
Synchronized getterはCASを使わない• Software Optimistic Lock Elision for Read-Only  ciritical sections(SOLERO) [Nakaie10]  – Obj...
Synchronized getterはCASを使わないclass Hoge {                                  class Hoge {                                    ...
参考文献• David Dice, “Implementing fast Java monitors  with relaxed locks”, In proceedings of the Java  Virtual Machine, Rese...
Upcoming SlideShare
Loading in …5
×

Jvm reading-synchronization

2,632 views

Published on

Jvm reading-synchronization

  1. 1. Locking and Synchronization第7回JVMソースコードリーディングの会 (OpenJDK) 中村 実 nminoru@nminoru.jp nminoru1975@gmail.com Twitter @nminoru_jp 1
  2. 2. Javaのスレッド排他機構• Objectはすべて同期オブジェクトになれる – Critical section型の排他処理 – 再帰的なロックも可能• 文法 – synchronizedメソッド – Synchronized文 • バイトコードレベルではmonitorenter、 monitorexit – wait & notify 2
  3. 3. Java Synchronizationの問題点• 安易に書けるため使いすぎる – 不要な場所にもsynchronizedを書いてしまう。 – 衝突しないsynchronizationが異常に多い。 class Hoge { int _hoge; public synchronized int getHoge() { return _hoge; } public synchronized void setHoge(int hoge) { _hoge = hoge; } } 3
  4. 4. Java Synchronizationの実装方法• 基本(Biased Locking以前) – -XX:-UseBiasedLocking• Biased Locking – -XX:+UseBiasedLocking(OpenJDK6ではデフォル ト) 4
  5. 5. Hotspotのlock関係のオプション-XX:+UseBiasedLocking BiasedLockingを有効に。-XX:-TraceMonitorInflation Inflation/deflation発生時にトレースを表示。-XX:-TraceBiasedLocking BaisedLockingに変更にトレースを表示。-XX:BiasedLockingStartupDelay=4000 VM起動後に時間をおいてからbiased locking を有効化する。その待機時間をミリ秒で指定。-XX:BiasedLockingBulkRebiasThreshold=20 Threshold of number of revocations per type to try to rebias all objects in the heap of that type-XX:BiasedLockingBulkRevokeThreshold=40 Threshold of number of revocations per type to permanently revoke biases of all objects in the heap of that type-XX:BiasedLockingDecayTime=25000 Decay time (in milliseconds) to re-enable bulk rebiasing of a type after previous bulk rebias-XX:-PrintBiasedLockingStatistics Print statistics of biased locking in JVM 5
  6. 6. 基本ロック 6
  7. 7. 基本ロックの方針• 衝突しないロック(uncontened lock)を効率 的に処理する• Phase1 (Lightweight) Locked – Unlock状態のオブジェクトに最初のスレッド がロックを行った状態。 – Thread-localなデータ構造だけで対応。• Phase2 Inflated – 第二以降のスレッドがロックを行い、thread- globalなデータ構造に変更する。これを inflationと呼ぶ。 7
  8. 8. ロックの構造体はどこにある?• oopの中にはない。• oopの第一ワードの_markは多目的用途で、 ロック時には切り替える(markOop.hpp) _mark hash code age 0 01 Normal(unlocked) _klass Pointer to basic lock 00 Locked Fields Pointer to monitor 10 Inflated lock JavaThread* epoch age 1 01 Biased 8
  9. 9. Phase 1• 最初のスレッドのロックはlocked状態へ遷移 – Interpreter frame上にBasicObjectLockを積むことでロックを表現 – 元の_markの内容を_displaced_headerへ退避 – _markはBasicLockの位置をComapre-And-Swap(CAS)で書き込む。 Object Interpreter frameTo basic lock 00 BasicLock _klass BasicObjectLock _lock : BasicLock _displaced_header Fields _obj 9
  10. 10. Phase 1• 処理コード InterpreterRuntime::monitorenter in interpreterRuntime.cpp:585 ObjectSynchronizer::fast_enter in synchronizer.cpp:155 ObjectSynchronizer::slow_enter in synchronizer.cpp:201 Under src/share/vm/runtime/• Recursive lockは? – Interpreter frameに複数のBasicObjectLockを積むことで 実現。• Unlockは – Stack unwind + α が unlock 処理。 – ObjectSynchronizer::fast_exit 10
  11. 11. Phase2 ObjectMonitor Object _header 前にあった_markを保存To monitor 10 _object ロック対象のoop _klass _owner ロックオーナー _recursions ロックの再帰回数(初回は0) Fields _cxq _EntryList … Owning Thread ObjectWaiter ObjectWaiter Blocked Thread _next _next _prev _prev Blocked Thread _thread _thread … … 11
  12. 12. Phase2• 処理コード – ObjectSynchronizer::inflate (inflation処理) – ObjectMonitor::enter (inflation後のロック処理)• 複数のスレッドが同時にinflationを試みるこ とがあるが、objectの_markをCASで書き換え ることで衝突判定している。• ObjectMonitorはスレッド毎にfree list管理され ておりinflateを実行しているスレッドが供出 する。 – ObjectSynchronizer::omAlloc 12
  13. 13. Biased Locking 13
  14. 14. Biased Lockingのコンセプト• もっとCAS命令の削除を – 基本ロックでは1回のロックで最低1回のCAS 命令を使う。• Biased Locking [Russell06] – あるスレッドからロックされたオブジェクト は、また同じスレッドからロックされる傾向 がある。 – オブジェクトの中にスレッド情報を埋め込ん で、特定のスレッドに偏っている(biased)こと を示す。そのスレッドからのロックはCASな しで済ませることが可能に。 14
  15. 15. Biased Lockingのコンセプト• どこにbiased threadを挿れるのか? – hash codeを潰す。 hash code age 0 01 Normal(unlocked) Thread id epoch age 1 01 Biased – hashcodeのフィールドは初期値は0で、hashが 最初に呼ばれた時に動的に設定される。 • hash()が呼ばれるとbiasedは解ける。 15
  16. 16. Biased Lockingのコンセプト• オブジェクト生成時はanonymously biased• 最初のスレッドがロックすると、そのスレッドのbiasがかかる(ここはCASが 必要)• Biasedのかかったスレッドがロックする場合は_markに変更が不要 – store-free- biased locking• ロックの衝突やその他が起きるとbiasをかけるのを止めて通常の状態に戻る。 – 以降、基本ロックを使用して元には戻らない。 Biasable Mode Normal Mode Initial lock 0 1 01 T 1 01 … 0 01anonymously biased biased toward given thread … 0 00 Revoke bias bulk rebias 16
  17. 17. Store-free biased locking(SFBL)BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS){ markOop mark = obj->mark(); if (mark->is_biased_anonymously() && !attempt_rebias) { // 初めてのロック } else if (mark->has_bias_pattern()) { Klass* k = Klass::cast(obj->klass()); markOop prototype_header = k->prototype_header(); if (!prototype_header->has_bias_pattern()) { // このクラスでは biased locking が許可されていない return BIAS_REVOKED; } else if (prototype_header->bias_epoch() != mark->bias_epoch()) { // epoch が一致しないので rebiased するか revoke する retrun } } HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias); if (heuristics == HR_NOT_BIASED) { return NOT_BIASED; // biased lokcing に成功 } 17
  18. 18. Bulk rebiasing and revocation• Bulk rebiasing – どのスレッドでbiasをかければいいのか時間 変化するので、一定周期でbiased toward given threadをanonymously biasedに戻す。• Bulk revocation – ある種のオブジェクトはbiased lockingに向か ない。 18
  19. 19. もっとCAS命令を減らしたい 19
  20. 20. Synchronized getterはCASを使わない• Software Optimistic Lock Elision for Read-Only ciritical sections(SOLERO) [Nakaie10] – Objectのヘッダにカウンタを用意 – JITを使って解析 Counter bits xx • オブジェクトのフィールドを変更するsync. method はcounerをアトミックに+1 • オブジェクトのフィールドを変更しない sync.methodはcounter読む→フィールド読む →counter再読み込みする。 • Counterが一致すれば成功。不一致なら通常の synchronization方式で再実行 20
  21. 21. Synchronized getterはCASを使わないclass Hoge { class Hoge { <<counter>> int _hoge; int _hoge; public synchronized int getHoge() { public synchronized int getHoge() { return _hoge; old = counter; } ret = _hoge; if (old == counter) return ret; // 再実行 } public synchronized void setHoge(int hoge) { public synchronized void setHoge(int hoge) { _hoge = hoge; fetchadd counter +1 } _hoge = hoge; }} } 21
  22. 22. 参考文献• David Dice, “Implementing fast Java monitors with relaxed locks”, In proceedings of the Java Virtual Machine, Research and Technology Symposium(JVM’01), April 2001, pp.79-90.• Kenneth Russell and David Detlefs, “Eliminating Synchronization-Related Atomic Operations with Biased Locking and Bulk Rebiasing”, OOPSLA’06, pp.• Takuya Nakaike and Maged M. Michael, “Lock Elision for Read-Only Critical Section in Java”, PLDI’10 22

×