JVM入門
 -Javaプログラムが動く仕組み-

87e6be3b5dcac822e5dfd974ba65045a?s=47 Kinoko
November 23, 2019

JVM入門
 -Javaプログラムが動く仕組み-

2019/11/23 JJUG CCC 2019 Fall - 日本Javaユーザーグループ 登壇資料です。

87e6be3b5dcac822e5dfd974ba65045a?s=128

Kinoko

November 23, 2019
Tweet

Transcript

  1. JVM⼊⾨
 Javaプログラムが動く仕組み Abe Asami (きの⼦)

  2. ⾃⼰紹介 "CF"TBNJl͖ͷࢠz
 େࡕͷϑϦʔϥϯεϓϩάϥϚ IUUQOPDPOPOFU !BBUI +BWB,PUMJO4DBMBͳͲͳͲ

  3. 最近やっていること https://www.geekhub.jp/
 ΤϯδχΞಛԽ߹ಉઆ໌ձΠϕϯτɻ࣍ճ 1/25(౔) ։࠵༧ఆ ʮJava11ʹΑΔ
 WebΞϓϦέʔγϣϯ։ൃͰֶͿ
 Javaϓϩάϥϛϯάೖ໳ʯൢചத https://www.udemy.com/java11-springbootweb-java/

  4. このセッションのターゲット • JavaͰ։ൃΛ͍ͯ͠Δ͕ɺJVM͕ԿΛ͍ͯ͠ Δͷ͔͸Α͘஌Βͳ͍ਓ • ώʔϓɺGCɺOutOfMemoryɺJITɺ HotSpotɺGraal…ͳͲͳͲ͍ΖΜͳ༻ޠΛࣖ ʹ͸͢Δ͕Α͘Θ͔Βͳ͍

  5. このセッションのゴール • JVMपΓͷ༻ޠ͕;ΜΘΓཧղͰ͖ΔΑ͏ʹͳΔ • JVM͕ԿΛ΍͍ͬͯΔ͔͕ͳΜͱͳ͘Θ͔ΔΑ͏ ʹͳΔ • JVMपΓͰࠔΓ͝ͱʹૺ۰ͨ͠৔߹ʹͲ͏ղੳ͠ ͯରॲ͢Ε͹͍͍ͷ͔ɺΞλϦΛ͚ͭΔ͜ͱ͕Ͱ ͖ΔΑ͏ʹͳΔ

  6. JVMとは?

  7. JavaVM (Java仮想マシン) • JavaόΠτίʔυΛ࣮ߦ͢ΔͨΊͷԾ૝؀ڥ • OSґଘΛٵऩ

  8. JDK‧JREとJVMの関係 • JRE(Java Runtime Environment) • JavaΛ࣮ߦ͢ΔͨΊʹඞཁͳιϑτ΢ΣΞηοτ • JVMΛؚΉ •

    JDK(Java Development Kit) • Javaͷιϑτ΢ΣΞ։ൃΛߦ͏ͨΊʹඞཁͳιϑτ΢ΣΞ ηοτ • JREΛؚΉ
  9. None
  10. Javaのコードが JVM上で動くまで

  11. Javaソースコード

  12. コンパイル

  13. Javaバイトコードを含む クラスファイルが⽣成される バイナリファイルであるため そのままだと読めないので、 「javap」コマンドで⼈間に読 める形に逆アセンブル

  14. 実⾏

  15. Hello! World!

  16. 実⾏の流れ ᶃ JVMىಈ ᶄ ϩʔυ
 (Ϋϥεϩʔμʔ͕ඞཁͳΫϥεϑΝΠϧΛಡΈࠐΉ) ᶅ ϦϯΫ(Ϋϥε͕ഁଛ͍ͯ͠ͳ͍͔ͷݕূ΍ࢀরͷղܾ) ᶆ ॳظԽ(staticϑΟʔϧυͷॳظԽͳͲ)

    ᶇ mainϝιου࣮ߦ
  17. バイトコードは1⾏ずつ実⾏される

  18. でもそれだと処理速度が遅い‧‧‧

  19. 「JITコンパイラ」 ͦ͜Ͱొ৔͢Δͷ͕

  20. JITコンパイラ
 (Just In Time Compiler) • ࣮ߦ࣌ʹίϯύΠϧΛߦ͍ॲཧΛ࠷దԽ͢Δ • ྫ͑͹Α͘ݺͼग़͞ΕΔॲཧʹ͍ͭͯ࠷ దԽΛߦͳ͏ͳͲɺ࣮ߦ݁ՌΛݩʹॲཧ

    Λߦͳ͏ • Java͸javacʹΑΔΫϥεϑΝΠϧ΁ͷίϯύ Πϧͱɺ͜ͷ࣮ߦ࣌ͷίϯύΠϧ͕͋Δ
  21. Javaバイトコードは「命令」 • JavaԾ૝Ϛγϯͷ໋ྩηοτ • ྫʣ
 i2fɾɾɾintΛfloatʹม׵
 faddɾɾɾfloatͷՃࢉΛߦͳ͏

  22. JVMはスタックマシン • ʮελοΫʯͱݺ͹ΕΔྖҬʹ໋ྩΛPushɾ Pop͠ͳ͕ΒɺϓϩάϥϜΛ࣮ߦ͍ͯ͘͠

  23. 実⾏イメージ バイトコードの命令を1⾏ず つ実⾏ 変数の値を読み込んでPush するという命令

  24. 値を2つpopし、⾜した結果 をPushするという命令

  25. このスタックは
 「オペランドスタック」

  26. メソッドを呼び出すと
 「フレーム」が作成されます

  27. 「メソッドフレーム」 これもスタック

  28. スタックトレース • ελοΫͷग़ྗ • ϝιουͷݺͼग़͠ͷཤྺ

  29. スタックオーバーフロー • ελοΫͷڐ༰ྔΛ௒͑Δͱ ʮStackOverflowErrorʯ

  30. スレッド スレッドの中に1つのスタック(メソッ ドフレーム)がある

  31. Javaはマルチスレッド

  32. スレッドダンプ • ͱ͋ΔॠؒͷεϨου(ελοΫͳͲ)ͷঢ়ଶ Λग़ྗͨ͠΋ͷ • jstack ɾjcmdίϚϯυͰग़ྗ͢Δ͜ͱ͕Ͱ͖ Δ • τϥϒϧൃੜ࣌ͷௐࠪ΍ύϑΥʔϚϯεɾ

    νϡʔχϯάʹ໾ཱͭ
  33. JVMの種類について

  34. JVMには種類がある • JVMͷ࢓༷͸JavaԾ૝Ϛγϯ࢓༷ʹΑͬͯن ఆ͞Ε͍ͯΔ͕ɺந৅త • classϑΝΠϧΛಡΈࠐΜͰਖ਼࣮͘͠ߦͰ ͖Ε͹OKͰ͋ͱ͸JVMͷ࣮૷ऀ࣍ୈ • ֤छϕϯμ͕ಠࣗJVMΛఏڙ͍ͯ͠Δ

  35. HotSpotVM • Oracleఏڙ • Ұ൪ϝδϟʔͰɺେମͷਓ͸͜ΕΛ࢖͍ͬͯ Δഺ • HotSpotͱ͍͏JITίϯύΠϥΛ࠾༻

  36. GraalVM • ͜Ε΋Oracleఏڙ • Graalͱ͍͏JITίϯύΠϥΛ࠾༻͍ͯ͠Δ • Ruby΍PythonͳͲଞݴޠΛ࣮ߦ͢Δػೳ΋ • AOTίϯύΠϧͰͷωΠςΟϒΠϝʔδԽ΋ ஫໨͞Ε͍ͯΔ

    ࠷ۙΑ͘ฉ͘
  37. AOTコンパイル • ࣄલίϯύΠϧ • JITͱҟͳΓɺJVMىಈલʹωΠςΟϒίʔ υ(=OS͕ղऍͰ͖Δίʔυ)ʹίϯύΠϧ • Java9͔Βಋೖ • HotSpotVMͰ΋࣮ݧతʹ(?)ಋೖ͞Ε͍ͯΔ

    ちょっとややこしいけど最近よく名前が出る‧‧‧
  38. JVMのメモリ管理

  39. 前提条件 • HotSpot VM Java8 • όʔδϣϯ΍JVMʹΑͬͯࠩҟ͕͋ͬͯ
 ΍΍͍͜͠ͷͰ

  40. JVMのメモリ構造

  41. プログラムで⽣成したオブジェク トはHeapに割り当てられる

  42. None
  43. None
  44. None
  45. None
  46. None
  47. これが「GC」

  48. GC(GarbageCollection) • ·ͣɺෆཁͱͳͬͨΦϒδΣΫτΛ୳͢ɻ • ෆཁͱ൑அͨ͠ϝϞϦΛղ์͢Δɻ

  49. None
  50. None
  51. None
  52. None
  53. None
  54. None
  55. ヒープのサイズはオプションで
 設定することができる % java -Xms600m -Xmx800m -Xloggc:gc.log -XX:+PrintGCDetails -XX: +PrintGCDateStamps

    Main -Xms ɾɾɾώʔϓͷॳظαΠζ
 -Xmx ɾɾɾώʔϓͷ࠷େαΠζ
  56. GCはとてもコストがかかります • GC༻ͷεϨου͕ඞཁ • GCର৅ͷΞϓϦέʔγϣϯεϨουΛࢭΊͯ ͠·͏ GCʹΑΓ௕࣌ؒΞϓϦέʔγϣϯ͕ࢭ·Δݱ৅Λ
 Stop the World

    (STW) ͱݺͿ
  57. GCには⾊々なアルゴリズムがある • Mark&Sweep • Copy • ੈ୅ผ

  58. GCには⾊々なアルゴリズムがある • Mark&Sweep • Copy • ੈ୅ผ これらのアルゴリズムを基本に、各JVMが独⾃でGCを実装している

  59. HotSpotVMのGCの種類 • γϦΞϧܕ • ύϥϨϧܕ • CMS • G1 ※

    Java にはShenandoah という新しいGCが実験的に追加されているそうです。 基本はJVM任せでOKだが、
 シビアなチューニングが必要な場合は
 それぞれのメリット‧デメリットを踏まえて選択する。
 (スループット重視かレスポンス重視か‧‧‧)
  60. いろいろあるけど
 「世代別」が基本となっているので 世代別GCについて説明します

  61. ヒープには「Young領域」と 「Old領域」があります

  62. オブジェクトはまずYoung領域に 作られます

  63. Young領域がいっぱいになってき たら‧‧‧

  64. Young領域だけGCが実⾏されます

  65. これを「マイナーGC」といいます

  66. GCされず、⽣き残った
 回数はカウントされます

  67. マイナーGCを繰り返す中でいつまでも
 残り「歳をとった」オブジェクトは‧‧‧

  68. Old領域に移動します

  69. もしOld領域もいっぱいになって きた場合‧‧‧

  70. ヒープ全域にGCが⾛ります

  71. これを「メジャー(Full )GC」とい います

  72. 実際のプログラムで GCの状況を解析してみる

  73. GCログ • GCͷॲཧ࣌ؒ΍લޙͷϝϞϦ࢖༻ྔͳͲͷϩ ά

  74. GCViewer • GCϩάͷϏϡʔΞʔ • https://github.com/chewiebug/GCViewer • 2019/07/18 ݱࡏɺJDK11ະରԠ

  75. とりあえず、 なんかしら動かして GCログを出してみる

  76. 参照が残らないインスタンスを
 ひたすら⽣成

  77. 実⾏ java -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps Main GCϩάग़ྗͷͨΊͷΦϓγϣϯ (※ඪ४ग़ྗʹग़͚ͩ͢Ͱ͋Ε͹ 
 -verbose:gc

    ͚͚ͩͭΕ͹OK)
  78. 出⼒されたログ

  79. GCViewerで開いてみる

  80. ΦϒδΣΫτ͸·ͣYoungྖҬʹ࡞ΒΕɺ
 ੜ੒͔Β͕࣌ؒܦͭͱOldྖҬʹҠಈ͢Δ

  81. ࠓճ͸OldྖҬ΁ͷҠಈ͕ൃੜ͠ͳ͍ͨΊ
 ώʔϓશମͷ࢖༻ྔ ≒ YoungྖҬͷώʔϓ࢖༻ྔ

  82. GC࣌ʹͪΌΜͱϝϞϦ͕ղ์͞Ε͍ͯΔ

  83. ϚΠφʔGCɾɾɾYoungྖҬͷΈ͕ର৅ YoungྖҬ͕
 ͍ͬͺ͍ʹͳͬͨ
 λΠϛϯάͰ
 ϚΠφʔGC͕
 ࣮ߦ͞Ε͍ͯΔ

  84. もう1パターン
 試してみる

  85. 参照が残るインスタンスを
 ひたすら⽣成

  86. GCログ

  87. これもGCViewerで開いてみる

  88. None
  89. Full GC (ϝδϟʔGC)ɾɾɾશώʔϓྖҬ͕ର৅

  90. Full GCは時間がかかる 2019-07-18T07:28:35.759-0900: 53.145: [GC (Allocation Failure) [PSYoungGen: 1153507K->190965K(1768960K)] 1400776K->506242K(2118656K),

    0.3026525 secs] [Times: user=2.55 sys=0.14, real=0.31 secs] 2019-07-18T07:28:36.064-0900: 53.450: [Full GC (Ergonomics) [PSYoungGen: 190965K->190932K(1768960K)] [ParOldGe 315276K->290297K(610816K)] 506242K->481229K(2379776K), [Metaspace: 2676K->2676K(1056768K)], 4.7517463 secs] [Times: user=29.92 sys=0.06, real=4.75 secs] ্ͷϚΠφʔGC ɾɾɾ 0.31 secs
 ԼͷFull GC ɾɾɾ 4.75 secs
  91. ヒープダンプ • ಛఆͷ࣌ࠁʹώʔϓ಺ʹؚ·ΕΔ͢΂ͯͷΦϒ δΣΫτͷεφοϓγϣοτ java -Xms600m -Xmx800m -Xloggc:gc.log -XX:+PrintGCDetails -XX:

    +PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError Main -XX:+HeapDumpOnOutOfMemoryError
 ɾɾɾ OOMEൃੜ࣌ʹώʔϓμϯϓΛग़ྗ
  92. まとめ • ීஈͷ։ൃͰ͋·Γҙࣝ͢Δ͜ͱ͸ͳ͍͚Ε Ͳ΋ɺಛʹӡ༻ϑΣʔζͰԿ͔τϥϒϧ͕ ͋ͬͨ৔߹ʹɺJVMͷ͜ͷลͷ஌͕ࣝ͋Δͱ ߄ͯͳͯ͘͢Ή (ଟ෼)

  93. ご清聴ありがとうござ いました。

  94. 参考資料 • JavaԾ૝Ϛγϯ࢓༷ (The Java series) • ಺༰͕ݹ͍ͷͰ஫ҙ • JavaύϑΥʔϚϯενϡʔχϯά

    ୈ2൛ • JavaͷϓϩάϥϜ͸Ͳ͏΍ͬͯಈ͍͍ͯΔͷ? JVMฤ https:// www.slideshare.net/skrb/java-jvm • JavaͷϓϩάϥϜ͸Ͳ͏΍ͬͯಈ͍͍ͯΔͷ? GCฤ https:// www.slideshare.net/skrb/java-gc-47402594
  95. • OutOfMemoryError ͷௐ΂ํ - Qiita https://qiita.com/opengl-8080/ items/64152ee9965441f7667b • Java͸ͲͷΑ͏ʹಈ͘ͷ͔ʙਤղͰΘ͔ΔJVMͷ࢓૊Έɿ࿈ࡌʛ gihyo.jp

    … ٕज़ධ࿦ࣾ http://gihyo.jp/dev/serial/01/jvm-arc • ʮϝϞϦʔΛҙࣝͯ͠ΈΑ͏ʯୈ2ճɹGCͷ࢓૊ΈΛཧղ͢Δ | ೔ܦ xTECHʢΫϩεςοΫʣ https://tech.nikkeibp.co.jp/it/article/ COLUMN/20060612/240657/?rt=nocnt • ·͡ΊʹJVMνϡʔχϯά: ୈ1ճ ·ͣ͸ݱঢ়֬ೝ https:// x1.inkenkun.com/archives/367