SlideShare a Scribd company logo
Submit Search
Upload
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
Report
N
NTT DATA Technology & Innovation
NTT DATA Technology & Innovation
Follow
•
3 likes
•
790 views
1
of
79
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
•
3 likes
•
790 views
Report
Technology
バイトコードって言葉をよく目にするけど一体何なんだろう? (JJUG CCC 2022 Spring 発表資料) 2022年6月19日(日) NTTデータ 技術開発本部 阪田 浩一
Read more
N
NTT DATA Technology & Innovation
NTT DATA Technology & Innovation
Follow
Recommended
HTTP/2 入門
Yahoo!デベロッパーネットワーク
63.7K views
•
33 slides
DockerとPodmanの比較
Akihiro Suda
47.6K views
•
37 slides
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
NTT DATA Technology & Innovation
2.6K views
•
53 slides
BuildKitによる高速でセキュアなイメージビルド
Akihiro Suda
42.5K views
•
27 slides
TLS, HTTP/2演習
shigeki_ohtsu
13.1K views
•
129 slides
アーキテクチャから理解するPostgreSQLのレプリケーション
Masahiko Sawada
30.2K views
•
69 slides
More Related Content
What's hot
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
Yahoo!デベロッパーネットワーク
13.3K views
•
15 slides
本当は恐ろしい分散システムの話
Kumazaki Hiroki
685.9K views
•
70 slides
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
Daichi Koike
2.5K views
•
54 slides
Dockerからcontainerdへの移行
Kohei Tokunaga
16.6K views
•
36 slides
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
Y Watanabe
17K views
•
78 slides
例外設計における大罪
Takuto Wada
68.5K views
•
37 slides
What's hot
(20)
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
Yahoo!デベロッパーネットワーク
•
13.3K views
本当は恐ろしい分散システムの話
Kumazaki Hiroki
•
685.9K views
OpenAPI 3.0でmicroserviceのAPI定義を試みてハマった話
Daichi Koike
•
2.5K views
Dockerからcontainerdへの移行
Kohei Tokunaga
•
16.6K views
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
Y Watanabe
•
17K views
例外設計における大罪
Takuto Wada
•
68.5K views
Redisの特徴と活用方法について
Yuji Otani
•
101.4K views
エンジニアの個人ブランディングと技術組織
Takafumi ONAKA
•
23.3K views
GKE に飛んでくるトラフィックを 自由自在に操る力 | 第 10 回 Google Cloud INSIDE Games & Apps Online
Google Cloud Platform - Japan
•
5.3K views
Twitterのsnowflakeについて
moai kids
•
24.8K views
世界一わかりやすいClean Architecture
Atsushi Nakamura
•
47K views
Docker Compose 徹底解説
Masahito Zembutsu
•
61.1K views
コンテナの作り方「Dockerは裏方で何をしているのか?」
Masahito Zembutsu
•
30.7K views
マイクロにしすぎた結果がこれだよ!
mosa siru
•
132.5K views
今なら間に合う分散型IDとEntra Verified ID
Naohiro Fujie
•
11.4K views
トランザクションの設計と進化
Kumazaki Hiroki
•
71.4K views
分散システムについて語らせてくれ
Kumazaki Hiroki
•
119.4K views
分散トレーシング技術について(Open tracingやjaeger)
NTT Communications Technology Development
•
23.2K views
関数型プログラミングのデザインパターンひとめぐり
Kazuyuki TAKASE
•
3K views
Kubernetes Service Account As Multi-Cloud Identity / Cloud Native Security Co...
Preferred Networks
•
2K views
Similar to バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
NTT DATA Technology & Innovation
2.1K views
•
84 slides
オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)
NTT DATA Technology & Innovation
1.3K views
•
62 slides
OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)
NTT DATA Technology & Innovation
392 views
•
81 slides
C#メタプログラミング概略 in 2021
Atsushi Nakamura
1.1K views
•
49 slides
Java 18で入ったJVM関連の(やや細かめな)改善(JJUGナイトセミナー「Java 18 リリース記念イベント」発表資料)
NTT DATA Technology & Innovation
1.2K views
•
55 slides
パターンでわかる! .NET Coreの非同期処理
Kouji Matsui
22.4K views
•
116 slides
Similar to バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
(20)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
NTT DATA Technology & Innovation
•
2.1K views
オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)
NTT DATA Technology & Innovation
•
1.3K views
OpenJDKのコミッタってどんなことしたらなったの?解決してきた技術課題の事例から見えてくる必要な知識と技術(JJUG CCC 2023 Spring)
NTT DATA Technology & Innovation
•
392 views
C#メタプログラミング概略 in 2021
Atsushi Nakamura
•
1.1K views
Java 18で入ったJVM関連の(やや細かめな)改善(JJUGナイトセミナー「Java 18 リリース記念イベント」発表資料)
NTT DATA Technology & Innovation
•
1.2K views
パターンでわかる! .NET Coreの非同期処理
Kouji Matsui
•
22.4K views
デブサミ2013【15-E-2】Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?
Developers Summit
•
1.5K views
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
NTT DATA Technology & Innovation
•
743 views
密着! nibohsiデプロイ 13:00-13:05 - railsアプリのデプロイ事例 -
Yukihiko SAWANOBORI
•
1.3K views
StackStorm Workflowの設計
Shu Sugimoto
•
1.2K views
オレ流のOpenJDKの開発環境(JJUG CCC 2019 Fall講演資料)
NTT DATA Technology & Innovation
•
1.8K views
Devsumi2013 Ruby開発者のみなさん、mrubyで楽しく快適な組み込みアプリ開発を始めませんか?
Takashi Sogabe
•
5K views
【GridDB入門】 IoT、そしてサイバー・フィジカル・システムを支える オープンソースデータベース GridDB ~ こだわりの理由と実現方法のポイント
griddb
•
369 views
Mbed祭り 2017@春の新横浜 20170225 竹之下
Koyo Takenoshita
•
944 views
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
Takeshi Yamamuro
•
10.7K views
自然言語処理に適した ニューラルネットのフレームワーク - - - DyNet - - -
Ogushi Masaya
•
3.5K views
インフラエンジニアがk8sでアプリを作って見えた今後のインフラ
susumu tanaka
•
11.4K views
20160115nodered design patterns
BMXUG
•
3.8K views
2015年度GPGPU実践プログラミング 第4回 GPUでの並列プログラミング(ベクトル和,移動平均,差分法)
智啓 出川
•
1K views
業務で ISUCON することになった話.pdf
TakuyaFukuoka2
•
175 views
More from NTT DATA Technology & Innovation
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
NTT DATA Technology & Innovation
87 views
•
63 slides
マネージドPostgreSQLの実現に向けたPostgreSQL機能向上(PostgreSQL Conference Japan 2023 発表資料)
NTT DATA Technology & Innovation
183 views
•
33 slides
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
NTT DATA Technology & Innovation
475 views
•
44 slides
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(Open Source Conference 202...
NTT DATA Technology & Innovation
115 views
•
44 slides
骨抜きアジャイルの骨を生み出す 〜私(スクラムマスター)のXP学習記録〜(XP祭り2023 発表資料)
NTT DATA Technology & Innovation
851 views
•
44 slides
機械学習モデルを REST API としてサービングするシステム開発における上流プロセスの絞り込みと効果検証(PM学会2023年度秋季研究発表大会 発表資料)
NTT DATA Technology & Innovation
74 views
•
21 slides
More from NTT DATA Technology & Innovation
(20)
pgvectorを使ってChatGPTとPostgreSQLを連携してみよう!(PostgreSQL Conference Japan 2023 発表資料)
NTT DATA Technology & Innovation
•
87 views
マネージドPostgreSQLの実現に向けたPostgreSQL機能向上(PostgreSQL Conference Japan 2023 発表資料)
NTT DATA Technology & Innovation
•
183 views
最新機能までを総ざらい!PostgreSQLの注目機能を振り返る(第32回 中国地方DB勉強会 in 岡山 発表資料)
NTT DATA Technology & Innovation
•
475 views
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(Open Source Conference 202...
NTT DATA Technology & Innovation
•
115 views
骨抜きアジャイルの骨を生み出す 〜私(スクラムマスター)のXP学習記録〜(XP祭り2023 発表資料)
NTT DATA Technology & Innovation
•
851 views
機械学習モデルを REST API としてサービングするシステム開発における上流プロセスの絞り込みと効果検証(PM学会2023年度秋季研究発表大会 発表資料)
NTT DATA Technology & Innovation
•
74 views
ChatGPTのデータソースにPostgreSQLを使う[詳細版](オープンデベロッパーズカンファレンス2023 発表資料)
NTT DATA Technology & Innovation
•
503 views
PostgreSQL on Kubernetes: Realizing High Availability with PGO (Postgres Ibiz...
NTT DATA Technology & Innovation
•
250 views
オンプレミス回帰の動きに備えよ ~クラウドの手法をオンプレミスでも実現するには~(CloudNative Days Fukuoka 2023 発表資料)
NTT DATA Technology & Innovation
•
118 views
Prometheus Operator 入門(Kubernetes Novice Tokyo #26 発表資料)
NTT DATA Technology & Innovation
•
428 views
ChatGPTのデータソースにPostgreSQLを使う(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
•
546 views
PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
•
266 views
どうする計画駆動型スクラム(スクラムフェス大阪2023 発表資料)
NTT DATA Technology & Innovation
•
990 views
YugabyteDBの拡張機能(YugabyteDB Meetup #2 発表資料)
NTT DATA Technology & Innovation
•
235 views
PGOを用いたPostgreSQL on Kubernetes入門(Open Source Conference 2023 Online/Hokkaido...
NTT DATA Technology & Innovation
•
466 views
GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)
NTT DATA Technology & Innovation
•
152 views
Memoizeの仕組み(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
•
927 views
PostgreSQL16新機能紹介 - libpq接続ロード・バランシング(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
•
749 views
明日から始める! ソフトウェアのグリーン化(GSF MeetUp Tokyo 発表資料)
NTT DATA Technology & Innovation
•
81 views
PostgreSQL16でのロールに関する変更点(第41回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
•
1.5K views
Recently uploaded
pandas便利だけどデフォルトパラメータでファイルを読み込むな!
Hiro H.
87 views
•
13 slides
概念モデリングワークショップ 設計編
Knowledge & Experience
9 views
•
37 slides
テストコードってすごい.pptx
cistb220msudou
70 views
•
16 slides
概念モデリングワークショップ 基礎編
Knowledge & Experience
16 views
•
71 slides
01Booster Studio ご紹介資料
ssusere7a2172
154 views
•
19 slides
さくらのひやおろし2023
法林浩之
11 views
•
58 slides
Recently uploaded
(9)
pandas便利だけどデフォルトパラメータでファイルを読み込むな!
Hiro H.
•
87 views
概念モデリングワークショップ 設計編
Knowledge & Experience
•
9 views
テストコードってすごい.pptx
cistb220msudou
•
70 views
概念モデリングワークショップ 基礎編
Knowledge & Experience
•
16 views
01Booster Studio ご紹介資料
ssusere7a2172
•
154 views
さくらのひやおろし2023
法林浩之
•
11 views
TaketoFujikawa_10thComicComputing2023
Matsushita Laboratory
•
81 views
DLゼミ: MobileOne: An Improved One millisecond Mobile Backbone
harmonylab
•
32 views
IKEv2-VPN PyHackCon2023
Takayuki Shimizukawa
•
19 views
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
1.
© 2022 NTT
DATA Corporation バイトコードって言葉をよく目にするけど一体何なんだろう? JJUG CCC 2022 Spring NTTデータ 阪田 浩一 2022年6月19日 • 想定視聴者: Javaプログラムを書いて実行したことがあればどなたもOK! • セッション録画公開: 有 • スライド公開: 有 - SlideShare(https://www.slideshare.net/nttdata-tech)を予定
2.
© 2022 NTT
DATA Corporation 2 自己紹介 • Javaチャンピオン • OpenJDK Author • 通算パッチ 10数個 • 株式会社NTTデータ 所属 • JVMがとにかく好き Koichi Sakata 阪田 浩一 jyukutyo
3.
© 2022 NTT
DATA Corporation 3 このセッションで話すこと 話すこと • プログラムを実行するまでの過程 • Javaバイトコードの概要 • Javaバイトコードを確認する方法 • 実は身近なバイトコード操作
4.
© 2022 NTT
DATA Corporation 4 このセッションで話すこと 話さないこと 話すこと • プログラムを実行するまでの過程 • Javaバイトコードの概要 • Javaバイトコードを確認する方法 • 実は身近なバイトコード操作 話さないこと • バイトコード操作の具体的なコードおよび詳細 • クラスファイル自体の内容 • その他上級者が求める範囲の内容
5.
© 2022 NTT
DATA Corporation 5 このセッションのゴール 参加された方が Javaプログラムを実行する仕組みの一部として バイトコードの役割や意味を他者に説明できるようになること 注意事項 • Javaコードはほぼ登場しません • 説明のため厳密には正確でない表現をすることがあります
6.
© 2022 NTT
DATA Corporation 6 プログラムを書いてから 実行するまで
7.
© 2022 NTT
DATA Corporation 7 Javaプログラムを書いてから実行するまで Javaプログラムを書き ファイルに保存する
8.
© 2022 NTT
DATA Corporation 8 Javaプログラムを書いてから実行するまで Javaプログラムを書き ファイルに保存する コンパイルし クラスファイルを生成する クラスを指定して実行する 注: Java 11から単一ファイルのとき`java HelloWorld.java`で実行できますが 内部的な処理は上と同一です プログラムを実行するまでに Javaではなぜこの手順が必要なの?
9.
© 2022 NTT
DATA Corporation 9 ハードウェアでの命令実行 • 機械語(マシン語)しか理解しない もうJavaじゃなくて機械語でプログラムを書けば いいんじゃないの?
10.
© 2022 NTT
DATA Corporation 10 ハードウェアでの命令実行 • 機械語(マシン語)しか理解しない • 機械語は0と1からなり 読み書きが困難である • 機 械 語 は CPU ア ー キ テ ク チ ャ や 使 用 す る OS に よって異なる それは辛い… じゃあJavaはコンパイルすると 機械語を生成するの?
11.
© 2022 NTT
DATA Corporation 11 それはC言語 どうしてJavaはこのやり方にしなかったの? Cプログラムを書き ファイルに保存する コンパイルし[1] 機械語を含んだ実行可能ファイルを生成する ファイルを指定して実行する [1]: プリプロセッサやリンカもコンパイラと一緒に動作しています
12.
© 2022 NTT
DATA Corporation 12 コンパイルで機械語を生成することの短所 コンパイルをした環境(OS CPU)でのみ動作する[1] • 実行可能ファイルを他の環境に配置しても実行できないということ - 再コンパイルを必要とする [1]: 正確には指定することで異なる環境向けにコンパイルできますが、今度はその環境でしか動作しません
13.
© 2022 NTT
DATA Corporation 13 コンパイルで機械語を生成することの短所 コンパイルをした環境(OS CPU)でのみ動作する[1] • 実行可能ファイルを他の環境に配置しても実行できないということ - 再コンパイルを必要とする [1]: 正確には指定することで異なる環境向けにコンパイルできますが、今度はその環境でしか動作しません 開発はmacOS 本番環境はLinux みたいなことがやりづらそう… そもそもコンパイルなんてなしにして プログラム実行時にソースコードから機械語に変えて 実行しちゃえばいいんじゃない?
14.
© 2022 NTT
DATA Corporation 14 インタープリタでの実行 def hello(name = "World") message = "Hello, " + name + ".¥n" puts message end hello() 1 2 3
15.
© 2022 NTT
DATA Corporation 15 インタープリタでの実行 def hello(name = "World") message = "Hello, " + name + ".¥n" puts message end hello() 1 2 3 • プ ロ グ ラ ム 実 行 時 に ソ ー ス コ ー ド [1] を 1 文 ず つ 機械語に変換し実行する(逐次解釈) • そのためこの手法を取るとコンパイルが不要となる • 実行時に解釈する処理は重く 動作が遅くなる インタ プリタ 実行 [1]: 厳密にはインタプリタの解釈の対象はソースコードに限定されるものではありません(後述) 注: RubyにはJITコンパイルでの実行もあります
16.
© 2022 NTT
DATA Corporation 16 2つのやり方とJava コンパイルして機械語を生成するやり方は 異なる環境で実行できない短所… インタープリタで逐次解釈するやり方は 動作が遅くなる短所…
17.
© 2022 NTT
DATA Corporation 17 2つのやり方とJava コンパイルして機械語を生成するやり方は 異なる環境で実行できない短所… インタープリタで逐次解釈するやり方は 動作が遅くなる短所… それにJavaのこと何も話していないよ! Javaは2つの方式を合わせ持っている バイトコードは2つを合わせる手段である
18.
© 2022 NTT
DATA Corporation 18 Javaコードと機械語 Javaコード • 機 械 語 に 変 え る の は 時間がかかる • テ キ ス ト フ ァ イ ル な の で どんなOSでも扱える
19.
© 2022 NTT
DATA Corporation 19 Javaコードと機械語 Javaコード • 機 械 語 に 変 え る の は 時間がかかる • テ キ ス ト フ ァ イ ル な の で どんなOSでも扱える 機械語 • そ の ま ま ハ ー ド ウ ェ ア で 実行できるため 速い • 特 定 の 環 境 で の み 動作する
20.
© 2022 NTT
DATA Corporation 20 Javaコードと機械語 Javaコード • 機 械 語 に 変 え る の は 時間がかかる • テ キ ス ト フ ァ イ ル な の で どんなOSでも扱える 機械語 • そ の ま ま ハ ー ド ウ ェ ア で 実行できるため 速い • 特 定 の 環 境 で の み 動作する ソースコードに比べて 機械語に変換しやすい ものにすれば 動作もある程度速く どんな環境でも利用できる 2つの中間に位置する そんなコードを作ろう!
21.
© 2022 NTT
DATA Corporation 21 Javaバイトコード コンパイル時に生成する • javacなどでのコンパイルのこと
22.
© 2022 NTT
DATA Corporation 22 Javaバイトコード コンパイル時に生成する • javacなどでのコンパイルのこと JVM独自の表現なのでどんな環境でも利用できる • その代わりバイトコードの実行にはJVMが必要となる - JVMが多数のプラットフォームをサポートするため大きな問題ではない
23.
© 2022 NTT
DATA Corporation 23 Javaプログラムを実行するということ Javaコード Javaバイトコード CAFE BABE 0000 javacなどでの コンパイル
24.
© 2022 NTT
DATA Corporation 24 Javaプログラムを実行するということ Javaコード 機械語 Javaバイトコード CAFE BABE 0000 javacなどでの コンパイル JVMの インタプリタ 注: JVMにはJITコンパイルでの実行もあります
25.
© 2022 NTT
DATA Corporation 25 Javaプログラムを実行するということ Javaコード 機械語 Javaバイトコード CAFE BABE 0000 javacなどでの コンパイル JVMの インタプリタ バイトコードはJavaコードよりは機械語に変換しやすいから インタプリタでの実行も向上する! バイトコードは環境に依存しなから JVMがあればどこでも動く! 注: JVMにはJITコンパイルでの実行もあります
26.
© 2022 NTT
DATA Corporation 26 JVMとJavaバイトコード
27.
© 2022 NTT
DATA Corporation 27 JVMでの演算 JVMは「スタック」上で演算をする • ハードウェア上ではCPUとメモリを使って処理をしているが 計算モデルとしてそう設計されている - スタックマシン
28.
© 2022 NTT
DATA Corporation 28 JVMでの演算 JVMは「スタック」上で演算をする • ハードウェア上ではCPUとメモリを使って処理をしているが 計算モデルとしてそう設計されている - スタックマシン • 例: 1 + 2の演算イメージ - 1、2という数値を 順にスタックに置き +という演算を スタックから2個の数値を取って 計算し結果をスタックに置く
29.
© 2022 NTT
DATA Corporation 29 JVMでの演算 JVMは「スタック」上で演算をする • もちろんハードウェア上ではCPUとメモリを使って処理をしているが 計算モデルとしてそう設計されている(スタックマシン) • 例: 1 + 2の演算イメージ - 最初スタックは空である - 1という数値を スタックに置く 1
30.
© 2022 NTT
DATA Corporation 30 JVMでの演算 JVMは「スタック」上で演算をする • もちろんハードウェア上ではCPUとメモリを使って処理をしているが 計算モデルとしてそう設計されている(スタックマシン) • 例: 1 + 2の演算イメージ - 1、2という数値を 順にスタックに置く +という演算は スタックから2個の数値を取り 結果をまたスタックに置く 1 1 2 3 2 1 + - int add(int a, int b)を使う呼び出し側も同じイメージでよい * 呼び出されたaddメソッド内の処理は別途あるけれども(詳細は後述)
31.
© 2022 NTT
DATA Corporation 31 JVMとJavaバイトコード 単純に言えばJavaバイトコードはJavaプログラムの内容を スタックでの処理として表現する
32.
© 2022 NTT
DATA Corporation 32 JVMとJavaバイトコード 単純に言えばJavaバイトコードはJavaプログラムの内容を スタックでの処理として表現する • スタックに何かを置いたり(プッシュ) 一番上から取ったり(ポップ) インスタンスを生成したり メソッドを呼び出したり など その表現のために使用するのがバイトコードの命令セット
33.
© 2022 NTT
DATA Corporation 33 Javaバイトコードの命令セット 200種類以上ある • Java仮想マシン(JVM)仕様に定義されている - https://docs.oracle.com/javase/specs/jvms/se18/html/jvms-6.html#jvms-6.5
34.
© 2022 NTT
DATA Corporation 34 Javaバイトコードの命令セット 200種類以上ある • Java仮想マシン(JVM)仕様に定義されている - https://docs.oracle.com/javase/specs/jvms/se18/html/jvms-6.html#jvms-6.5 • 命令コード(オペコード)が1バイト長 - 1バイト = 28 = 256種類までしか定義できないことになる - Javaのリリース以来 追加した命令コードは1つだけ * Project Valhallaで2つ追加する見込み
35.
© 2022 NTT
DATA Corporation 35 Javaバイトコードの命令セット 200種類以上ある • Java仮想マシン(JVM)仕様に定義されている - https://docs.oracle.com/javase/specs/jvms/se18/html/jvms-6.html#jvms-6.5 • 命令コード(オペコード)が1バイト長 - 1バイト = 28 = 256種類までしか定義できないことになる - Javaのリリース以来 追加した命令コードは1つだけ * Project Valhallaで2つ追加する見込み • 暗記する必要はとくにない - 型違い(プリミティブ型各種類と参照型で同じ内容)の命令コードも多い - スタックでの利用をイメージすると理解しやすい
36.
© 2022 NTT
DATA Corporation 36 Javaバイトコードの命令コードの読み方 接頭辞の例 i... int[1] l... long f... float d... double [1]: intの他byte、short、char、booleanなどもJVMではintで扱います(例外有)
37.
© 2022 NTT
DATA Corporation 37 Javaバイトコードの命令セットの読み方 接頭辞の例 i... int[1] l... long f... float d... double 命令内容の例 const 定数をプッシュ add,sub,mul,div 2つポップしてそれらで 四則演算し結果をプッシュ [1]: intの他byte、short、char、booleanなどもJVMではintで扱います(例外有) 接頭辞にある型と命令を組み合わせで 数が多くなっているのか 命令の例: iconst_1: スタックに定数1をプッシュ idiv:スタックにあるint値を2つポップして除算 結果をスタックにプッシュ fmul: スタックにあるfloat値を2つポップして乗算 結果をスタックにプッシュ
38.
© 2022 NTT
DATA Corporation 38 Javaバイトコードの命令セットの読み方 接頭辞の例 i... int[1] l... long f... float d... double 命令内容の例 const 定数をプッシュ add,sub,mul,div 2つポップしてそれらで 四則演算し結果をプッシュ [1]: intの他byte、short、char、booleanなどもJVMではintで扱います(例外有) 1 + 2は 1. iconst_1 2. iconst_2 3. iadd となる 3 2 1 + 1 2 命令コードからスタックを操作する絵を描いてみると わかりやすいなあ
39.
© 2022 NTT
DATA Corporation 39 Javaバイトコードの命令セットの読み方 接頭辞の例 i... int[1] l... long f... float d... double a... 参照型 *a... 1文字目の型の配列 ia...だとint配列 命令内容の例 const 定数をプッシュ load ローカル変数をプッシュ store ローカル変数に保存 return 戻り値として返す 2 プリミティブ型変換 (例: i2d) add,sub,mul,div 四則演算 neg 符号反転 [1]: intの他byte、short、char、booleanなどもJVMではintで扱います(例外有) 注: 各命令でスタックからのポップやスタックへのプッシュがあります 注: 接頭辞と命令内容のすべての組み合わせが 命令に存在するわけではありません
40.
© 2022 NTT
DATA Corporation 40 メソッド処理のバイトコード表現を考えてみよう int add(int a, int b) { return a + b; } 引数aとbはどうなるの? スタックにプッシュしたい 録画再生の方は停止して30秒間考えてみましょう
41.
© 2022 NTT
DATA Corporation 41 メソッド処理のバイトコード表現を考えてみよう int add(int a, int b) { return a + b; } a b iload_1はローカル変数の1番目を スタックにプッシュするのか iconst_1の_1とは違うんだ 1. メソッド開始時スタックは空 2. iload_1 • 引数はローカル変数に保存されている - インスタンスメソッドではローカル変数の 0番にthis 1番目以降に引数の値が入っている 3. iload_2 - 引数の2つ目である2番目をプッシュ a
42.
© 2022 NTT
DATA Corporation 42 メソッド処理のバイトコード表現を考えてみよう int add(int a, int b) { return a + b; } a+b b a + a b 1. メソッド開始時スタックは空 2. iload_1 • 引数はローカル変数に保存されている - インスタンスメソッドではローカル変数の 0番にthis 1番目以降に引数の値 3. iload_2 4. iadd 5. ireturn a メソッドの 呼び出し元へ
43.
© 2022 NTT
DATA Corporation 43 組み合わせでない命令の例 メソッド呼び出し invokestatic staticメソッド呼出 invokevirtual インスタンスメソッド invokespecial コンストラクタ、private、 スーパークラスメソッド invokeinterface インタフェースメソッド invokedynamic 動的に算出した コールサイトの呼出[1] [1]: 複雑な仕組みのためこのセッション内に理解する必要はありません invoke...はメソッド呼び出しと 捉えておけばいいか このinvokedynamicこそが 後から追加された唯一のバイトコード
44.
© 2022 NTT
DATA Corporation 44 組み合わせでない命令の例 メソッド呼び出し invokestatic staticメソッド呼出 invokevirtual インスタンスメソッド 他 new,newarray インスタンス生成 pop,pop2 スタックからポップ dup... 複製をプッシュ putfield,putstatic フィールドに値をセット ldc... Constant Poolの値をプッシュ monitorenter,monitorexit ロックの確保、解放 注:すべての命令は 記載していません invokespecial コンストラクタ、private、 スーパークラスメソッド invokeinterface インタフェースメソッド invokedynamic 動的に算出した コールサイトの呼出[1] [1]: 複雑な仕組みのためこのセッション内に理解する必要はありません
45.
© 2022 NTT
DATA Corporation 45 メソッド呼び出しのバイトコード表現を考えてみよう 録画再生の方は停止して30秒間考えてみましょう class Sample { int add(int a, int b) { return a + b; } } // 以下はメインメソッドの中とする Sample s = new Sample(); s.add(1, 2); 引数aとbはどうなるの? スタックにプッシュしたい
46.
© 2022 NTT
DATA Corporation 46 メソッド呼び出しのバイトコード表現を考えてみよう class Sample { int add(int a, int b) { return a + b; } } // 以下はメインメソッドの中とする Sample s = new Sample(); int a = s.add(1, 2); #数字 はConstant Pool(定数プール) を番号で参照している クラス名 メソッド名なども CPに保持している 1. new #7 2. dup 3. invokespecial #9 4. astore_1 5. aload_1 6. iconst_1 7. iconst_2 8. invokevirtual #10 9. istore_2 10. return なぜdupして 複製するの?
47.
© 2022 NTT
DATA Corporation 47 インスタンス生成とコンストラクタ呼び出し JVMではこの2つは別の処理 Sample s = new Sample(); 1. new #7 2. dup 3. invokespecial #9 4. astore_1 Sam Sam Sam newでSampleインスタンスへの 参照を積む
48.
© 2022 NTT
DATA Corporation 48 インスタンス生成とコンストラクタ呼び出し JVMではこの2つは別の処理 Sample s = new Sample(); 1. new #7 2. dup 3. invokespecial #9 4. astore_1 Sam Sam Sam Sam Sam invokespecialで コンストラクタ 呼び出し Sam ローカル変数1に 保存 コンストラクタ実行 ローカル変数への保存 それぞれで参照を使用するため 複製して2つ用意した • 何かをするためにはスタックから取り出さなければならない newでSampleインスタンスへの 参照を積む
49.
© 2022 NTT
DATA Corporation 49 Javaバイトコードを 実際に見てみよう
50.
© 2022 NTT
DATA Corporation 50 Javaバイトコードとクラスファイル バイトコードはクラスファイルに含まれる • クラスファイルの中を見てみよう!
51.
© 2022 NTT
DATA Corporation 51 クラスファイルの中 - add()を呼び出すクラス げ、げぇー iconstとかiaddとかない どういうこと??
52.
© 2022 NTT
DATA Corporation 52 Javaバイトコードとクラスファイル バイトコードはクラスファイルに含まれる クラスファイルはバイナリファイル • テキストファイルではない
53.
© 2022 NTT
DATA Corporation 53 Javaバイトコードとクラスファイル バイトコードはクラスファイルに含まれる クラスファイルはバイナリファイル • テキストファイルではない • 各バイトコード命令に対応する数字がファイルに含まれる iconst_1 4 (0x4) iconst_2 5 (0x5) iadd 96 (0x60) 今まで出てきたのは バイトコードのニーモニックということか… じゃあクラスファイルを逆アセンブルすればいい?
54.
© 2022 NTT
DATA Corporation 54 javapコマンド クラスファイルを逆アセンブルするツール • https://docs.oracle.com/en/java/javase/17/docs/specs/man/javap.html • JDKに含まれる - JAVA_HOMEにパスを通していればすぐに使える
55.
© 2022 NTT
DATA Corporation 55 javapコマンド クラスファイルを逆アセンブルするツール • https://docs.oracle.com/en/java/javase/17/docs/specs/man/javap.html • JDKに含まれる - JAVA_HOMEにパスを通していればすぐに使える • -c: コードを逆アセンブル または -v: 詳細に出力 を使う • 詳細は--helpで確認できる
56.
© 2022 NTT
DATA Corporation 56 javapコマンドでの逆アセンブル
57.
© 2022 NTT
DATA Corporation 57 Constant Poolも見れる javap -v の出力に含まれる
58.
© 2022 NTT
DATA Corporation 58 <init>は コンストラクタのことを 指しているんだ
59.
© 2022 NTT
DATA Corporation 59 バイトコードの楽しみ方
60.
© 2022 NTT
DATA Corporation 60 バイトコードの楽しみ方 1. 読む! 2. 書き換える!
61.
© 2022 NTT
DATA Corporation 61 バイトコードの楽しみ方 1. 読む! 2. 書き換える!
62.
© 2022 NTT
DATA Corporation 62 バイトコードを読む Javaの新バージョンリリースで新機能が出た • 新機能を使うコードを書いてバイトコードを見る
63.
© 2022 NTT
DATA Corporation 63 バイトコードを読む Javaの新バージョンリリースで新機能が出た • 新機能を使うコードを書いてバイトコードを見る 新バージョンで同じ処理でも バイトコード表現に変更があることも
64.
© 2022 NTT
DATA Corporation 64 バイトコードを読む Javaの新バージョンリリースで新機能が出た • 新機能を使うコードを書いてバイトコードを見る 新バージョンで同じ処理でも バイトコード表現に変更があることも - 例: ネストしたクラスを作り インナークラスから アウタークラスのprivateメソッドを呼び出すコード * Java 11で変わった(Nestmates/ネストメイト)
65.
© 2022 NTT
DATA Corporation 65 Nestmates public class Outer { private void m_outerpriv() { System.out.println("called m_outerpriv"); } class Inner { public void test() { new Outer().m_outerpriv(); } } public static void main(String[] args) { new Outer().new Inner().test(); } }
66.
© 2022 NTT
DATA Corporation 66 Java 8でコンパイルした結果をjavapで見る public class Outer { private void m_outerpriv() { System.out.println("called m_outerpriv"); } class Inner { public void test() { new Outer().m_outerpriv(); } } public static void main(String[] args) { new Outer().new Inner().test(); } }
67.
© 2022 NTT
DATA Corporation 67
68.
© 2022 NTT
DATA Corporation 68 Java 8でコンパイルした結果をjavapで見る Outerにaccess$000(Outer) というstaticメソッドが!? InnerはOuterインスタンスを生成し access$000を呼び出している public class Outer { private void m_outerpriv() { System.out.println("called m_outerpriv"); } class Inner { public void test() { new Outer().m_outerpriv(); } } public static void main(String[] args) { new Outer().new Inner().test(); } }
69.
© 2022 NTT
DATA Corporation 69 Java 8でコンパイルした結果をjavapで見る Outerにaccess$000(Outer) というstaticメソッドが!? InnerはOuterインスタンスを 生成し access$000を 呼び出している なぜこんなことを? • フィールドまたはメソッドRにアクセス可能 なクラスまたはインタフェースDとは、以下 のことが真となる場合のみに限る。 • Rがprivateでその宣言がDにある。 - インナークラスにこのprivateメソッドは 宣言されていないため直接呼び出せない - JVM仕様 5.5.4 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms- 5.html#jvms-5.4.4 コンパイラが勝手に生成する メソッドを合成メソッドという public class Outer { private void m_outerpriv() { System.out.println("called m_outerpriv"); } class Inner { public void test() { new Outer().m_outerpriv(); } } public static void main(String[] args) { new Outer().new Inner().test(); } }
70.
© 2022 NTT
DATA Corporation 70 Java 11以降でコンパイルした結果をjavapで見る public class Outer { private void m_outerpriv() { System.out.println("called m_outerpriv"); } class Inner { public void test() { new Outer().m_outerpriv(); } } public static void main(String[] args) { new Outer().new Inner().test(); } }
71.
© 2022 NTT
DATA Corporation 71 Java 11以降でコンパイルした結果をjavapで見る 何が変わった? • Java 11でクラスファイルに新しい属性が追加された - ネスト関係をこの属性で把握できる $ javap -v Outer ... NestMembers: Outer$Inner $ javap -v Outer¥$Inner ... NestHost: class Outer
72.
© 2022 NTT
DATA Corporation 72 Java 11以降でコンパイルした結果をjavapで見る 何が変わった? • Java 11でクラスファイルに新しい属性が追加された - ネスト関係をこの属性で把握できる $ javap -v Outer ... NestMembers: Outer$Inner $ javap -v Outer¥$Inner ... NestHost: class Outer • JVM仕様5.4.4も変更されている - R is private and is declared by a class or interface C that belongs to the same nest as D, according to the nestmate test below. * https://docs.oracle.com/javase/specs/jvms/se18/html/jvms-5.html#jvms- 5.4.4 • この変更によりprivateメソッドが 直接呼び出せるようになった 私のブログにも書いています https://www.sakatakoichi.com/entry/java11nestmates
73.
© 2022 NTT
DATA Corporation 73 バイトコードの楽しみ方 1. 読む! 2. 書き換える! ぎょ、ぎょえー これを手で書き換えるの?
74.
© 2022 NTT
DATA Corporation 74 バイトコード操作ライブラリ ライブラリを使いJavaコードでバイトコード命令を書き換える • ASM https://asm.ow2.io/ • CGLIB https://github.com/cglib/cglib • Javassist https://www.javassist.org/ • Byte Buddy https://bytebuddy.net/#/ ASMはAPIの抽象度が低い Byte Buddyは抽象度が 高い
75.
© 2022 NTT
DATA Corporation 75 バイトコード操作ライブラリ ライブラリを使いJavaコードでバイトコード命令を書き換える • ASM https://asm.ow2.io/ • CGLIB https://github.com/cglib/cglib • Javassist https://www.javassist.org/ • Byte Buddy https://bytebuddy.net/#/ 操作手順イメージ 1. クラスファイルを読み込む 2. Javaコードでバイトコードを書き換える(処理の追加 変更 削除) 3. 書き換えた内容を適用する - コンパイル時やビルド時はクラスファイル出力 実行時はクラスロード ASMはAPIの抽象度が低い Byte Buddyは抽象度が 高いイメージ
76.
© 2022 NTT
DATA Corporation 76 ByteBuddyでの操作サンプルコード ByteBuddy byteBuddy = new ByteBuddy(); byteBuddy .redefine(TypePool.Default.of(classLoader).describe("a.b.Hello").resolve(), ClassFileLocator.ForClassLoader.of(classLoader)) .method(ElementMatchers.named("toString")) .intercept(FixedValue.value("transformed")) .make() .load(classLoader, ClassReloadingStrategy.of(inst)); // inst = java.lang.instrument.Instrumentationオブジェクト a.b.HelloクラスのtoString()メソッドを "transformed"と返すように書き換えたって感じに読める 最後はJDKのInstrument APIを使って 書き換えたクラスをロードさせて使われるようにした
77.
© 2022 NTT
DATA Corporation 77 ソースコードを直接変更すればいいのでは…? そう! でも変更したくない/できないケースもある • フレームワークやライブラリが アプリケーションで作成したクラスに 対して拡張を施したいとき - 例: Spring Hibernate • モックオブジェクトを作るとき - 例: jMockit Mockito * テストコード実行時にメソッドの内容をモック用に書き換えてしまうイメージ[1] 普段使っているフレームワークやライブラリでも バイトコードを操作しているんだ Bytecode Enhancement とも言う [1]: 新たにサブクラスを作るなどいろいろなやり方があります
78.
© 2022 NTT
DATA Corporation 78 バイトコードを知って何の意味があるの? フレームワークが使うだけなら 私たちがバイトコードを知る必要はとくにないのでは… • 明日からすぐ業務に役立つ内容ではありません • ただし技術の習得には2つの側面があります - 車輪の両輪であり 2つをバランス良く習得することが大切です 使 い 方 を 学 ぶ 仕 組 み を 学 ぶ • 使用する技術がどのように実現 されているのかを学ぶこと • 実行の仕組み 設計概念 内部的表現 • 目 的 と す る ア プ リ ケ ー シ ョ ン を 作成するためにそれをどのように 使えばよいかを学ぶこと • 言 語 構 文 FW の 設 定 ライブラリの使い方
79.
© 2022 NTT
DATA Corporation 本資料に記載されている会社名、商品名、又はサービス名は、各社の登録商標又は商標です。