Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JVM入門 -Javaプログラムが動く仕組み-
Search
Kinoko
November 23, 2019
Technology
35
13k
JVM入門 -Javaプログラムが動く仕組み-
2019/11/23 JJUG CCC 2019 Fall - 日本Javaユーザーグループ 登壇資料です。
Kinoko
November 23, 2019
Tweet
Share
More Decks by Kinoko
See All by Kinoko
自作キーボードにチャレンジしてみた。 ver 2.0
sammy7th
0
1.9k
私が考える理想の開発チーム
sammy7th
0
600
ビジネスルールを軸とした ソフトウェア開発手法 「CCSR」
sammy7th
7
2.5k
お家に居れなくなって 3週間ゲストハウス暮らしをしていた話
sammy7th
2
480
家で仕事中にインターフォンに気づかず困っているのでIoTでなんとかしたい
sammy7th
1
150
ホットサンドメーカーで作るスイーツ
sammy7th
0
240
Udemyでプログラミング の動画講座を販売してみた
sammy7th
1
820
Git運用基礎
sammy7th
1
260
エンジニア向け合同説明会「就活GeekHub」イベント説明
sammy7th
1
2.8k
Other Decks in Technology
See All in Technology
AWSではじめる Web APIテスト実践ガイド / A practical guide to testing Web APIs on AWS
yokawasa
7
550
手を動かしてレベルアップしよう!
maruto
0
170
AWS Well-Architected Frameworkで学ぶAmazon ECSのセキュリティ対策
umekou
2
130
Share my, our lessons from the road to re:Invent
naospon
0
130
わたしがEMとして入社した「最初の100日」の過ごし方 / EMConfJp2025
daiksy
13
4.4k
サイト信頼性エンジニアリングとAmazon Web Services / SRE and AWS
ymotongpoo
7
1.3k
Perlの生きのこり - エンジニアがこの先生きのこるためのカンファレンス2025
kfly8
2
260
わたしのOSS活動
kazupon
2
340
実は強い 非ViTな画像認識モデル
tattaka
2
1.1k
Amazon Aurora のバージョンアップ手法について
smt7174
2
130
遷移の高速化 ヤフートップの試行錯誤
narirou
6
1k
What's new in Go 1.24?
ciarana
1
100
Featured
See All Featured
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
175
52k
YesSQL, Process and Tooling at Scale
rocio
172
14k
Designing for Performance
lara
604
68k
Documentation Writing (for coders)
carmenintech
67
4.6k
Thoughts on Productivity
jonyablonski
69
4.5k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
10
510
Six Lessons from altMBA
skipperchong
27
3.6k
4 Signs Your Business is Dying
shpigford
182
22k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
193
16k
How to Ace a Technical Interview
jacobian
276
23k
For a Future-Friendly Web
brad_frost
176
9.6k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.4k
Transcript
JVM⼊⾨ Javaプログラムが動く仕組み Abe Asami (きの⼦)
⾃⼰紹介 "CF"TBNJl͖ͷࢠz େࡕͷϑϦʔϥϯεϓϩάϥϚ IUUQOPDPOPOFU !BBUI +BWB,PUMJO4DBMBͳͲͳͲ
最近やっていること https://www.geekhub.jp/ ΤϯδχΞಛԽ߹ಉઆ໌ձΠϕϯτɻ࣍ճ 1/25() ։࠵༧ఆ ʮJava11ʹΑΔ WebΞϓϦέʔγϣϯ։ൃͰֶͿ Javaϓϩάϥϛϯάೖʯൢചத https://www.udemy.com/java11-springbootweb-java/
このセッションのターゲット • JavaͰ։ൃΛ͍ͯ͠Δ͕ɺJVM͕ԿΛ͍ͯ͠ Δͷ͔Α͘Βͳ͍ਓ • ώʔϓɺGCɺOutOfMemoryɺJITɺ HotSpotɺGraal…ͳͲͳͲ͍ΖΜͳ༻ޠΛࣖ ʹ͢Δ͕Α͘Θ͔Βͳ͍
このセッションのゴール • JVMपΓͷ༻ޠ͕;ΜΘΓཧղͰ͖ΔΑ͏ʹͳΔ • JVM͕ԿΛ͍ͬͯΔ͔͕ͳΜͱͳ͘Θ͔ΔΑ͏ ʹͳΔ • JVMपΓͰࠔΓ͝ͱʹૺ۰ͨ͠߹ʹͲ͏ղੳ͠ ͯରॲ͢Ε͍͍ͷ͔ɺΞλϦΛ͚ͭΔ͜ͱ͕Ͱ ͖ΔΑ͏ʹͳΔ
JVMとは?
JavaVM (Java仮想マシン) • JavaόΠτίʔυΛ࣮ߦ͢ΔͨΊͷԾڥ • OSґଘΛٵऩ
JDK‧JREとJVMの関係 • JRE(Java Runtime Environment) • JavaΛ࣮ߦ͢ΔͨΊʹඞཁͳιϑτΣΞηοτ • JVMΛؚΉ •
JDK(Java Development Kit) • JavaͷιϑτΣΞ։ൃΛߦ͏ͨΊʹඞཁͳιϑτΣΞ ηοτ • JREΛؚΉ
None
Javaのコードが JVM上で動くまで
Javaソースコード
コンパイル
Javaバイトコードを含む クラスファイルが⽣成される バイナリファイルであるため そのままだと読めないので、 「javap」コマンドで⼈間に読 める形に逆アセンブル
実⾏
Hello! World!
実⾏の流れ ᶃ JVMىಈ ᶄ ϩʔυ (Ϋϥεϩʔμʔ͕ඞཁͳΫϥεϑΝΠϧΛಡΈࠐΉ) ᶅ ϦϯΫ(Ϋϥε͕ഁଛ͍ͯ͠ͳ͍͔ͷݕূࢀরͷղܾ) ᶆ ॳظԽ(staticϑΟʔϧυͷॳظԽͳͲ)
ᶇ mainϝιου࣮ߦ
バイトコードは1⾏ずつ実⾏される
でもそれだと処理速度が遅い‧‧‧
「JITコンパイラ」 ͦ͜Ͱొ͢Δͷ͕
JITコンパイラ (Just In Time Compiler) • ࣮ߦ࣌ʹίϯύΠϧΛߦ͍ॲཧΛ࠷దԽ͢Δ • ྫ͑Α͘ݺͼग़͞ΕΔॲཧʹ͍ͭͯ࠷ దԽΛߦͳ͏ͳͲɺ࣮ߦ݁ՌΛݩʹॲཧ
Λߦͳ͏ • JavajavacʹΑΔΫϥεϑΝΠϧͷίϯύ Πϧͱɺ͜ͷ࣮ߦ࣌ͷίϯύΠϧ͕͋Δ
Javaバイトコードは「命令」 • JavaԾϚγϯͷ໋ྩηοτ • ྫʣ i2fɾɾɾintΛfloatʹม faddɾɾɾfloatͷՃࢉΛߦͳ͏
JVMはスタックマシン • ʮελοΫʯͱݺΕΔྖҬʹ໋ྩΛPushɾ Pop͠ͳ͕ΒɺϓϩάϥϜΛ࣮ߦ͍ͯ͘͠
実⾏イメージ バイトコードの命令を1⾏ず つ実⾏ 変数の値を読み込んでPush するという命令
値を2つpopし、⾜した結果 をPushするという命令
このスタックは 「オペランドスタック」
メソッドを呼び出すと 「フレーム」が作成されます
「メソッドフレーム」 これもスタック
スタックトレース • ελοΫͷग़ྗ • ϝιουͷݺͼग़͠ͷཤྺ
スタックオーバーフロー • ελοΫͷڐ༰ྔΛ͑Δͱ ʮStackOverflowErrorʯ
スレッド スレッドの中に1つのスタック(メソッ ドフレーム)がある
Javaはマルチスレッド
スレッドダンプ • ͱ͋ΔॠؒͷεϨου(ελοΫͳͲ)ͷঢ়ଶ Λग़ྗͨ͠ͷ • jstack ɾjcmdίϚϯυͰग़ྗ͢Δ͜ͱ͕Ͱ͖ Δ • τϥϒϧൃੜ࣌ͷௐࠪύϑΥʔϚϯεɾ
νϡʔχϯάʹཱͭ
JVMの種類について
JVMには種類がある • JVMͷ༷JavaԾϚγϯ༷ʹΑͬͯن ఆ͞Ε͍ͯΔ͕ɺநత • classϑΝΠϧΛಡΈࠐΜͰਖ਼࣮͘͠ߦͰ ͖ΕOKͰ͋ͱJVMͷ࣮ऀ࣍ୈ • ֤छϕϯμ͕ಠࣗJVMΛఏڙ͍ͯ͠Δ
HotSpotVM • Oracleఏڙ • Ұ൪ϝδϟʔͰɺେମͷਓ͜ΕΛ͍ͬͯ Δഺ • HotSpotͱ͍͏JITίϯύΠϥΛ࠾༻
GraalVM • ͜ΕOracleఏڙ • Graalͱ͍͏JITίϯύΠϥΛ࠾༻͍ͯ͠Δ • RubyPythonͳͲଞݴޠΛ࣮ߦ͢Δػೳ • AOTίϯύΠϧͰͷωΠςΟϒΠϝʔδԽ ͞Ε͍ͯΔ
࠷ۙΑ͘ฉ͘
AOTコンパイル • ࣄલίϯύΠϧ • JITͱҟͳΓɺJVMىಈલʹωΠςΟϒίʔ υ(=OS͕ղऍͰ͖Δίʔυ)ʹίϯύΠϧ • Java9͔Βಋೖ • HotSpotVMͰ࣮ݧతʹ(?)ಋೖ͞Ε͍ͯΔ
ちょっとややこしいけど最近よく名前が出る‧‧‧
JVMのメモリ管理
前提条件 • HotSpot VM Java8 • όʔδϣϯJVMʹΑͬͯࠩҟ͕͋ͬͯ ͍͜͠ͷͰ
JVMのメモリ構造
プログラムで⽣成したオブジェク トはHeapに割り当てられる
None
None
None
None
None
これが「GC」
GC(GarbageCollection) • ·ͣɺෆཁͱͳͬͨΦϒδΣΫτΛ୳͢ɻ • ෆཁͱஅͨ͠ϝϞϦΛղ์͢Δɻ
None
None
None
None
None
None
ヒープのサイズはオプションで 設定することができる % java -Xms600m -Xmx800m -Xloggc:gc.log -XX:+PrintGCDetails -XX: +PrintGCDateStamps
Main -Xms ɾɾɾώʔϓͷॳظαΠζ -Xmx ɾɾɾώʔϓͷ࠷େαΠζ
GCはとてもコストがかかります • GC༻ͷεϨου͕ඞཁ • GCରͷΞϓϦέʔγϣϯεϨουΛࢭΊͯ ͠·͏ GCʹΑΓ࣌ؒΞϓϦέʔγϣϯ͕ࢭ·ΔݱΛ Stop the World
(STW) ͱݺͿ
GCには⾊々なアルゴリズムがある • Mark&Sweep • Copy • ੈผ
GCには⾊々なアルゴリズムがある • Mark&Sweep • Copy • ੈผ これらのアルゴリズムを基本に、各JVMが独⾃でGCを実装している
HotSpotVMのGCの種類 • γϦΞϧܕ • ύϥϨϧܕ • CMS • G1 ※
Java にはShenandoah という新しいGCが実験的に追加されているそうです。 基本はJVM任せでOKだが、 シビアなチューニングが必要な場合は それぞれのメリット‧デメリットを踏まえて選択する。 (スループット重視かレスポンス重視か‧‧‧)
いろいろあるけど 「世代別」が基本となっているので 世代別GCについて説明します
ヒープには「Young領域」と 「Old領域」があります
オブジェクトはまずYoung領域に 作られます
Young領域がいっぱいになってき たら‧‧‧
Young領域だけGCが実⾏されます
これを「マイナーGC」といいます
GCされず、⽣き残った 回数はカウントされます
マイナーGCを繰り返す中でいつまでも 残り「歳をとった」オブジェクトは‧‧‧
Old領域に移動します
もしOld領域もいっぱいになって きた場合‧‧‧
ヒープ全域にGCが⾛ります
これを「メジャー(Full )GC」とい います
実際のプログラムで GCの状況を解析してみる
GCログ • GCͷॲཧ࣌ؒલޙͷϝϞϦ༻ྔͳͲͷϩ ά
GCViewer • GCϩάͷϏϡʔΞʔ • https://github.com/chewiebug/GCViewer • 2019/07/18 ݱࡏɺJDK11ະରԠ
とりあえず、 なんかしら動かして GCログを出してみる
参照が残らないインスタンスを ひたすら⽣成
実⾏ java -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps Main GCϩάग़ྗͷͨΊͷΦϓγϣϯ (※ඪ४ग़ྗʹग़͚ͩ͢Ͱ͋Ε -verbose:gc
͚͚ͩͭΕOK)
出⼒されたログ
GCViewerで開いてみる
ΦϒδΣΫτ·ͣYoungྖҬʹ࡞ΒΕɺ ੜ͔Β͕࣌ؒܦͭͱOldྖҬʹҠಈ͢Δ
ࠓճOldྖҬͷҠಈ͕ൃੜ͠ͳ͍ͨΊ ώʔϓશମͷ༻ྔ ≒ YoungྖҬͷώʔϓ༻ྔ
GC࣌ʹͪΌΜͱϝϞϦ͕ղ์͞Ε͍ͯΔ
ϚΠφʔGCɾɾɾYoungྖҬͷΈ͕ର YoungྖҬ͕ ͍ͬͺ͍ʹͳͬͨ λΠϛϯάͰ ϚΠφʔGC͕ ࣮ߦ͞Ε͍ͯΔ
もう1パターン 試してみる
参照が残るインスタンスを ひたすら⽣成
GCログ
これもGCViewerで開いてみる
None
Full GC (ϝδϟʔGC)ɾɾɾશώʔϓྖҬ͕ର
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
ヒープダンプ • ಛఆͷ࣌ࠁʹώʔϓʹؚ·ΕΔͯ͢ͷΦϒ δΣΫτͷεφοϓγϣοτ java -Xms600m -Xmx800m -Xloggc:gc.log -XX:+PrintGCDetails -XX:
+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError Main -XX:+HeapDumpOnOutOfMemoryError ɾɾɾ OOMEൃੜ࣌ʹώʔϓμϯϓΛग़ྗ
まとめ • ීஈͷ։ൃͰ͋·Γҙࣝ͢Δ͜ͱͳ͍͚Ε Ͳɺಛʹӡ༻ϑΣʔζͰԿ͔τϥϒϧ͕ ͋ͬͨ߹ʹɺJVMͷ͜ͷลͷ͕ࣝ͋Δͱ ߄ͯͳͯ͘͢Ή (ଟ)
ご清聴ありがとうござ いました。
参考資料 • 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
• 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