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.

HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ JVM 特集 2015年8月]

777 views

Published on

Java 言語レベルでのロックの振る舞いや使い方を説明する本や記事などの資料はいろいろありますが、JVM 側の内部実装についての説明は殆どありません。
このセッションで、HotSpot のロックの実装を覗いてみます。

HotSpot 側のロックの各種(thin、inflated、biased など)の実装とパフォーマンスの特徴を勉強しましょう。そして、プロファイリングツールを使って自分のシステムのロック利用を監視する例と JVM の設定も軽くカバーします。

Published in: Software
  • Be the first to comment

  • Be the first to like this

HotSpot のロック: A Peek Under the Hood [JJUG ナイトセミナ JVM 特集 2015年8月]

  1. 1. HotSpot のロック A Peek Under the Hood David Buck 日本オラクル JJUG ナイトセミナ JVM特集
  2. 2. 自己紹介 バック デイビッド • Java SE サステイニング エンジニアリング • JVM のバグを直す人 • 趣味:プログラミング
  3. 3. 予定 • はじめに • Java ロックの復習 • HotSpot のロックの実装 • プロファイリング&チューニング • その他
  4. 4. はじめに
  5. 5. カバーする内容 synchronized(this) { c++; }
  6. 6. カバーする内容 synchronized(this) { c++; }
  7. 7. カバーする内容 3: monitorenter 4: aload_0 5: dup 6: getfield #2 // Field c:I 9: iconst_1 10: iadd 11: putfield #2 // Field c:I 14: aload_1 15: monitorexit
  8. 8. カバーする内容 3: monitorenter 4: aload_0 5: dup 6: getfield #2 // Field c:I 9: iconst_1 10: iadd 11: putfield #2 // Field c:I 14: aload_1 15: monitorexit
  9. 9. カバーしない内容
  10. 10. カバーしない内容 • ロックの使い方
  11. 11. カバーしない内容 • ロックの使い方 • java.util.concurrent (JSR-166)
  12. 12. カバーしない内容 • ロックの使い方 • java.util.concurrent (JSR-166) • Java のメモリ・モデル
  13. 13. 目標
  14. 14. 目標 • 無理やり最適化を防ぐ
  15. 15. 目標 • 無理やり最適化を防ぐ • プロファイリング・チューニング
  16. 16. 目標 • 無理やり最適化を防ぐ • プロファイリング・チューニング • 面白い!
  17. 17. JAVA ロックの復習
  18. 18. 言語レベルでマルチスレッド
  19. 19. • Monitor って何?
  20. 20. (排他制御) Mutual Exclusion
  21. 21. (排他制御) Mutual Exclusion Mut ex
  22. 22. (排他制御) Mutual Exclusion Mutex
  23. 23. 条件変数 (condition variable) "Puffin crossing, London, UK" by secretlondon is licensed under CC BY-SA 3.0
  24. 24. Monitor = Mutex + 条件変数
  25. 25. Monitor = Mutex + 条件変数 • Mutex – synchronized キーワード
  26. 26. Monitor = Mutex + 条件変数 • Mutex – synchronized キーワード • 条件変数 – Object.wait() – Object.notify() – Object.notifyAll()
  27. 27. 再帰的 public synchronized void increment() { c++; printValue(); } public synchronized void printValue() { System.out.println("My value is: " + c); }
  28. 28. メモリ モデル happens-before ( 前に発生)関係
  29. 29. public class NoSync { private int c = 0; public void increment() { c++; } }
  30. 30. public void increment(); flags: ACC_PUBLIC Code: stack=3, locals=1, args_size=1 0: aload_0 1: dup 2: getfield #2 // Field c:I 5: iconst_1 6: iadd 7: putfield #2 // Field c:I 10: return
  31. 31. ブロックの例 public void increment() { synchronized(this) { c++; } }
  32. 32. ブロックの例 public void increment(); flags: ACC_PUBLIC Code: stack=3, locals=3, args_size=1 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: dup 6: getfield #2 // Field c:I 9: iconst_1 10: iadd 11: putfield #2 // Field c:I 14: aload_1 15: monitorexit 16: goto 24 19: astore_2 20: aload_1 21: monitorexit 22: aload_2 23: athrow 24: return Exception table: from to target type 4 16 19 any 19 22 19 any
  33. 33. ブロックの例 public void increment(); flags: ACC_PUBLIC Code: stack=3, locals=3, args_size=1 0: aload_0 1: dup 2: astore_1 3: monitorenter 4: aload_0 5: dup 6: getfield #2 // Field c:I 9: iconst_1 10: iadd 11: putfield #2 // Field c:I 14: aload_1 15: monitorexit 16: goto 24 19: astore_2 20: aload_1 21: monitorexit 22: aload_2 23: athrow 24: return Exception table: from to target type 4 16 19 any 19 22 19 any
  34. 34. メソッドの例 public synchronized void increment() { c++; }
  35. 35. メソッドの例 public synchronized void increment(); flags: ACC_PUBLIC, ACC_SYNCHRONIZED Code: stack=3, locals=1, args_size=1 0: aload_0 1: dup 2: getfield #2 // Field c:I 5: iconst_1 6: iadd 7: putfield #2 // Field c:I 10: return
  36. 36. メソッドの例 public synchronized void increment(); flags: ACC_PUBLIC, ACC_SYNCHRONIZED Code: stack=3, locals=1, args_size=1 0: aload_0 1: dup 2: getfield #2 // Field c:I 5: iconst_1 6: iadd 7: putfield #2 // Field c:I 10: return
  37. 37. Java 言語で表現出来ない public void lockMe(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: monitorenter 2: return public void unlockMe(); flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: monitorexit 2: return
  38. 38. Java バイトコード 表現力 Java 言語
  39. 39. Java Monitor の制限
  40. 40. Java Monitor の制限 • テスト不可能
  41. 41. Java Monitor の制限 • テスト不可能 • タイムアウト無し
  42. 42. Java Monitor の制限 • テスト不可能 • タイムアウト無し • キャンセル不可能
  43. 43. Java Monitor の制限 • テスト不可能 • タイムアウト無し • キャンセル不可能 • 再帰出来る
  44. 44. Java Monitor の制限 • テスト不可能 • タイムアウト無し • キャンセル不可能 • 再帰出来る • リーダー/ライターに分けることが不可能
  45. 45. Java Monitor の制限 • テスト不可能 • タイムアウト無し • キャンセル不可能 • 再帰出来る • リーダー/ライターに分けることが不可能 • セキュリティの問題
  46. 46. java.util.concurrent
  47. 47. HOTSPOT のロックの実装
  48. 48. 設計の方針 • すべてのオブジェクトが Monitor を持つ • 殆どのオブジェクトが利用しない • 利用しても、複数のスレッドからのアクセスが 珍しい • 複数のスレッドからアクセスがあっても、競合 が珍しい
  49. 49. ロックの種類 • Fat • Thin • Biased
  50. 50. Biased Thin Fat 重さ
  51. 51. Fat ロック • OS のスケジューリングに任せる • 得意ケース:待ち時間が高い • 別名:Heavyweight lock, inflated ロック
  52. 52. Thin ロック • ロック取得出来るまでスピンする • 得意ケース:待ち時間が短い • 別名:spin lock, stack lock (HS), lightweight lock
  53. 53. Biased ロック • 一本のスレッドが独占する • 違うスレッドが bias を revoke する場合がある
  54. 54. BiasedLock の revoke • Bias を持つスレッドの停止(STW) • 本当の状態の確認(スタックウォーキング)
  55. 55. BiasedLock の禁止 • オブジェクトレベル • クラスレベル • 起動中の処理
  56. 56. 各オブジェクトで管理するデータ • フィールドのデータ • Monitor の状態 • GC のデータ(Age など) • Hash コード
  57. 57. オブジェクトヘッダー フィールドのデータ クラスポインター マークワード
  58. 58. 忙しいマークワード マークワード Hashcode GC データ Monitor
  59. 59. Hashcode GC データ Monitor 00データ
  60. 60. Thin Locked Hashcode GC データ Monitor 00移動されたヘッダーの参照
  61. 61. Inflating Hashcode GC データ Monitor 00NULL
  62. 62. ロックされていない Biased Locking 不可能 Hashcode GC データ Monitor 01未使用 0 Age / CMS Hashcode
  63. 63. Biased Hashcode GC データ Monitor 01未使用 1 Age / CMS スレッドのID と Epoc
  64. 64. Fat Locked Hashcode GC データ Monitor 01Monitor の参照
  65. 65. GC 実行中(STW) Hashcode GC データ Monitor 11GC 用
  66. 66. Lock Record コピーされたマークワード オブジェクト参照
  67. 67. Lock Record コピーされたマークワード オブジェクト参照 01 Age / CMS Hash code オブジェクト参照 スレッドのスタック
  68. 68. Thin Lock 01 Age / CMS Hash code オブジェクト参照 フィールドのデータ クラスポインター 参照 00 スレッドのスタック オブジェクト
  69. 69. Thin Lock (再帰的) 01 Age / CMS Hash code オブジェクト参照 フィルドのデータ クラスポインター 参照 00 スレッドのスタック オブジェクト 未使用 オブジェクト参照
  70. 70. Fat Lock フィールドのデータ クラスポインター 参照 00 11未使用 オブジェクト参照 スレッドのスタック オブジェクト ObjectMonitor 01 Age / CMS Hash code オブジェクト参照
  71. 71. ロックの遷移図
  72. 72. Biased Thin Fat 重さ
  73. 73. プロファイリング&チューニング
  74. 74. プロファイリング 問題点:パフォーマンスのインパクト
  75. 75. プロファイリング • Performance Counters • DTrace • Java Flight Recorder
  76. 76. Performance Counters • パフォーマンスへのインパクトなし • 正式にサポートされていない • HotSpot の開発者向けの情報 • 例: jstat -snap -J-Djstat.showUnsupported=true <JVM_PID> |grep _sync
  77. 77. DTrace • 高い柔軟性 • D 言語の理解が不可欠 • サポートされている OS – Solaris – Oracle Linux – OSX • -XX:+DTraceMonitorProbes が必要
  78. 78. DTrace ロック系のプローブ • monitor-contended-enter • monitor-contended-entered • monitor-contended-exit
  79. 79. DTrace 条件変数系のプローブ • monitor-wait • monitor-waited • monitor-notify • monitor-notifyAll
  80. 80. Java Flight Recorder • 無料(開発・評価) • サポート: OracleJDK のすべての OS
  81. 81. 設定 • PrintConcurrentLocks • UseBiasedLocking • DTraceMonitorProbes • BiasedLockingStartupDelay • PrintBiasedLockingStatistics • TraceBiasedLocking • TraceMonitorInflation • MonitorInUseLists • TraceMonitorMismatch • UseHeavyMonitors • BiasedLockingBulkRebiasThreshold • BiasedLockingBulkRevokeThreshold • BiasedLockingDecayTime • SyncKnobs
  82. 82. PrintConcurrentLocks • java.util.concurrent のロックがスレッドダンプ で表示される
  83. 83. UseBiasedLocking • Biased ロックを無効にする • ロック競合が激しい環境は試す価値がある
  84. 84. その他
  85. 85. Concurrent Programming in Java™: Design Principles and Patterns • JDK 1.2のごろ – JSR-133 なし – JSR-166 なし • 設計が注目される • クラシック
  86. 86. Java Concurrency in Practice • JDK 1.6 ごろ – JSR-133 あり – JSR-166 あり • 一冊しか読む余裕な い方:これ!
  87. 87. まとめ • JVM に任せよう • Monitor で実現出来ない時、 java.util.concurrent を利用しよう • プロファイリング: JFR か DTrace – 要注意:パフォーマンスへのインパクト • CPiJ と JCiP を読むべき
  88. 88. ありがとうございます
  89. 89. 参照 • [ jstat man page ] https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html • [ DTrace Probes in HotSpot VM ] http://docs.oracle.com/javase/8/docs/technotes/guides/vm/dtrace.html • [ JMC Tutorial ] http://hirt.se/blog/?p=611 • [ David Dice's Weblog ] https://blogs.oracle.com/dave/ • [ HotSpot Internals ] https://wiki.openjdk.java.net/display/HotSpot/Main

×