SlideShare a Scribd company logo
1 of 22
Locking and Synchronization
第7回JVMソースコードリーディングの会
         (OpenJDK)
              中村 実
      nminoru@nminoru.jp
     nminoru1975@gmail.com
       Twitter @nminoru_jp


                              1
Javaのスレッド排他機構
• Objectはすべて同期オブジェクトになれる
 – Critical section型の排他処理
 – 再帰的なロックも可能
• 文法
 – synchronizedメソッド
 – Synchronized文
    • バイトコードレベルではmonitorenter、 monitorexit
 – wait & notify

                                         2
Java Synchronizationの問題点
• 安易に書けるため使いすぎる
 – 不要な場所にもsynchronizedを書いてしまう。
 – 衝突しないsynchronizationが異常に多い。

 class Hoge {
     int    _hoge;
     public synchronized int getHoge() {
       return _hoge;
     }
     public synchronized void setHoge(int hoge) {
         _hoge = hoge;
     }
 }
                                                    3
Java Synchronizationの実装方法
• 基本(Biased Locking以前)
  – -XX:-UseBiasedLocking
• Biased Locking
  – -XX:+UseBiasedLocking(OpenJDK6ではデフォル
    ト)




                                           4
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
基本ロックの方針
• 衝突しないロック(uncontened lock)を効率
  的に処理する
• Phase1 (Lightweight) Locked
  – Unlock状態のオブジェクトに最初のスレッド
    がロックを行った状態。
  – Thread-localなデータ構造だけで対応。
• Phase2 Inflated
  – 第二以降のスレッドがロックを行い、thread-
    globalなデータ構造に変更する。これを
    inflationと呼ぶ。
                                 7
ロックの構造体はどこにある?
• 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
Phase 1
• 最初のスレッドのロックはlocked状態へ遷移
   – Interpreter frame上にBasicObjectLockを積むことでロックを表現
   – 元の_markの内容を_displaced_headerへ退避
   – _markはBasicLockの位置をComapre-And-Swap(CAS)で書き込む。




     Object
                        Interpreter frame
To basic lock 00
                                                BasicLock
    _klass              BasicObjectLock
                        _lock : BasicLock   _displaced_header
     Fields                   _obj


                                                            9
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
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
Phase2
• 処理コード
  – ObjectSynchronizer::inflate (inflation処理)
  – ObjectMonitor::enter (inflation後のロック処理)
• 複数のスレッドが同時にinflationを試みるこ
  とがあるが、objectの_markをCASで書き換え
  ることで衝突判定している。
• ObjectMonitorはスレッド毎にfree list管理され
  ておりinflateを実行しているスレッドが供出
  する。
  – ObjectSynchronizer::omAlloc
                                                12
Biased Locking




                 13
Biased Lockingのコンセプト
• もっとCAS命令の削除を
  – 基本ロックでは1回のロックで最低1回のCAS
    命令を使う。
• Biased Locking [Russell06]
  – あるスレッドからロックされたオブジェクト
    は、また同じスレッドからロックされる傾向
    がある。
  – オブジェクトの中にスレッド情報を埋め込ん
    で、特定のスレッドに偏っている(biased)こと
    を示す。そのスレッドからのロックはCASな
    しで済ませることが可能に。
                               14
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
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 01
anonymously biased             biased toward given thread
                                                                    …      0 00
                                                     Revoke bias
                      bulk rebias
                                                                                  16
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
Bulk rebiasing and revocation
• Bulk rebiasing
  – どのスレッドでbiasをかければいいのか時間
    変化するので、一定周期でbiased toward given
    threadをanonymously biasedに戻す。
• Bulk revocation
  – ある種のオブジェクトはbiased lockingに向か
    ない。



                                    18
もっとCAS命令を減らしたい




                 19
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
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
参考文献
• 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

More Related Content

What's hot

イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術Kohsuke Yuasa
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッドKohsuke Yuasa
 
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16Mitsuru Kariya
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3DKouji Hosoda
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Keisuke Fukuda
 
effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36Tatsuki SHIMIZU
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会Koichi Sakata
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みChihiro Ito
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccYujiSoftware
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎信之 岩永
 
データサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるデータサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるShintaro Fukushima
 
今日からはじめるGPars
今日からはじめるGPars今日からはじめるGPars
今日からはじめるGParsfumokmm
 
デバドラを書いてみよう!
デバドラを書いてみよう!デバドラを書いてみよう!
デバドラを書いてみよう!Masami Ichikawa
 
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Ransui Iso
 

What's hot (20)

emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術イマドキC++erのモテカワリソース管理術
イマドキC++erのモテカワリソース管理術
 
規格書で読むC++11のスレッド
規格書で読むC++11のスレッド規格書で読むC++11のスレッド
規格書で読むC++11のスレッド
 
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
 
Async design with Unity3D
Async design with Unity3DAsync design with Unity3D
Async design with Unity3D
 
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
 
Effective modern-c++#9
Effective modern-c++#9Effective modern-c++#9
Effective modern-c++#9
 
effective modern c++ chapeter36
effective modern c++ chapeter36effective modern c++ chapeter36
effective modern c++ chapeter36
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 
関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会関ジャバ JavaOne Tokyo 2012報告会
関ジャバ JavaOne Tokyo 2012報告会
 
講座Java入門
講座Java入門講座Java入門
講座Java入門
 
C++ マルチスレッド 入門
C++ マルチスレッド 入門C++ マルチスレッド 入門
C++ マルチスレッド 入門
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_cccJEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 
データサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるデータサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみる
 
今日からはじめるGPars
今日からはじめるGPars今日からはじめるGPars
今日からはじめるGPars
 
Slub data structure
Slub data structureSlub data structure
Slub data structure
 
デバドラを書いてみよう!
デバドラを書いてみよう!デバドラを書いてみよう!
デバドラを書いてみよう!
 
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
 

Similar to Jvm reading-synchronization

Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageTaku Miyakawa
 
node-handlersocket
node-handlersocketnode-handlersocket
node-handlersocketkoichik
 
Oracle Database In Lock
Oracle Database In LockOracle Database In Lock
Oracle Database In LockRyota Watabe
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8y_taka_23
 
tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)
tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)
tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)Iwana Chan
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patternsnekop
 
PostgreSQL運用管理入門
PostgreSQL運用管理入門PostgreSQL運用管理入門
PostgreSQL運用管理入門Yoshiyuki Asaba
 
Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Kazuki Ohta
 
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]David Buck
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safeKumazaki Hiroki
 
197x 20090704 Scalaで並行プログラミング
197x 20090704 Scalaで並行プログラミング197x 20090704 Scalaで並行プログラミング
197x 20090704 Scalaで並行プログラミングNet Penguin
 
HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ JVM 特集 2015年8月]
HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ  JVM 特集  2015年8月]HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ  JVM 特集  2015年8月]
HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ JVM 特集 2015年8月]David Buck
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsuNanha Park
 
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...Masahiro Sakai
 
述語ロックの歴史 r2
述語ロックの歴史 r2述語ロックの歴史 r2
述語ロックの歴史 r2Sho Nakazono
 
2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理
2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理
2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理keki3
 
Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義JPCERT Coordination Center
 

Similar to Jvm reading-synchronization (19)

Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
 
Jvm reading-parallel gc
Jvm reading-parallel gcJvm reading-parallel gc
Jvm reading-parallel gc
 
Clojure
ClojureClojure
Clojure
 
node-handlersocket
node-handlersocketnode-handlersocket
node-handlersocket
 
Oracle Database In Lock
Oracle Database In LockOracle Database In Lock
Oracle Database In Lock
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)
tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)
tokyo.vcl発表資料(VarnishCache3.0新機能とVUPの仕方)
 
ClassLoader Leak Patterns
ClassLoader Leak PatternsClassLoader Leak Patterns
ClassLoader Leak Patterns
 
PostgreSQL運用管理入門
PostgreSQL運用管理入門PostgreSQL運用管理入門
PostgreSQL運用管理入門
 
Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方
 
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
JDK 13 New Features [MeetUp with Java Experts! @Gaienmae/Dojima 2019]
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
197x 20090704 Scalaで並行プログラミング
197x 20090704 Scalaで並行プログラミング197x 20090704 Scalaで並行プログラミング
197x 20090704 Scalaで並行プログラミング
 
HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ JVM 特集 2015年8月]
HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ  JVM 特集  2015年8月]HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ  JVM 特集  2015年8月]
HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ JVM 特集 2015年8月]
 
Nodejuku01 ohtsu
Nodejuku01 ohtsuNodejuku01 ohtsu
Nodejuku01 ohtsu
 
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...“Design and Implementation of Generics for the .NET Common Language Runtime”他...
“Design and Implementation of Generics for the .NET Common Language Runtime”他...
 
述語ロックの歴史 r2
述語ロックの歴史 r2述語ロックの歴史 r2
述語ロックの歴史 r2
 
2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理
2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理
2018年度 若手技術者向け講座 大量データの扱い・ストアド・メモリ管理
 
Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義Javaセキュアコーディングセミナー東京第1回 講義
Javaセキュアコーディングセミナー東京第1回 講義
 

Jvm reading-synchronization

  • 1. Locking and Synchronization 第7回JVMソースコードリーディングの会 (OpenJDK) 中村 実 nminoru@nminoru.jp nminoru1975@gmail.com Twitter @nminoru_jp 1
  • 2. Javaのスレッド排他機構 • Objectはすべて同期オブジェクトになれる – Critical section型の排他処理 – 再帰的なロックも可能 • 文法 – synchronizedメソッド – Synchronized文 • バイトコードレベルではmonitorenter、 monitorexit – wait & notify 2
  • 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. Java Synchronizationの実装方法 • 基本(Biased Locking以前) – -XX:-UseBiasedLocking • Biased Locking – -XX:+UseBiasedLocking(OpenJDK6ではデフォル ト) 4
  • 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
  • 7. 基本ロックの方針 • 衝突しないロック(uncontened lock)を効率 的に処理する • Phase1 (Lightweight) Locked – Unlock状態のオブジェクトに最初のスレッド がロックを行った状態。 – Thread-localなデータ構造だけで対応。 • Phase2 Inflated – 第二以降のスレッドがロックを行い、thread- globalなデータ構造に変更する。これを inflationと呼ぶ。 7
  • 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. Phase 1 • 最初のスレッドのロックはlocked状態へ遷移 – Interpreter frame上にBasicObjectLockを積むことでロックを表現 – 元の_markの内容を_displaced_headerへ退避 – _markはBasicLockの位置をComapre-And-Swap(CAS)で書き込む。 Object Interpreter frame To basic lock 00 BasicLock _klass BasicObjectLock _lock : BasicLock _displaced_header Fields _obj 9
  • 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. 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. Phase2 • 処理コード – ObjectSynchronizer::inflate (inflation処理) – ObjectMonitor::enter (inflation後のロック処理) • 複数のスレッドが同時にinflationを試みるこ とがあるが、objectの_markをCASで書き換え ることで衝突判定している。 • ObjectMonitorはスレッド毎にfree list管理され ておりinflateを実行しているスレッドが供出 する。 – ObjectSynchronizer::omAlloc 12
  • 14. Biased Lockingのコンセプト • もっとCAS命令の削除を – 基本ロックでは1回のロックで最低1回のCAS 命令を使う。 • Biased Locking [Russell06] – あるスレッドからロックされたオブジェクト は、また同じスレッドからロックされる傾向 がある。 – オブジェクトの中にスレッド情報を埋め込ん で、特定のスレッドに偏っている(biased)こと を示す。そのスレッドからのロックはCASな しで済ませることが可能に。 14
  • 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. 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 01 anonymously biased biased toward given thread … 0 00 Revoke bias bulk rebias 16
  • 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. Bulk rebiasing and revocation • Bulk rebiasing – どのスレッドでbiasをかければいいのか時間 変化するので、一定周期でbiased toward given threadをanonymously biasedに戻す。 • Bulk revocation – ある種のオブジェクトはbiased lockingに向か ない。 18
  • 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. 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. 参考文献 • 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