SlideShare a Scribd company logo
1 of 36
Download to read offline
2018年12月15日
数村 憲治
GCを発生させない
JVMとコーディングスタイル
Copyright 2018 FUJITSU LIMITED0
JJUG CCC 2018 Fall
.setName(“数村憲治”)
.setDirectorOf(“Eclipse Foundation Board”)
.setMemberOf(“Jakarta EE Committee”)
.setMemberOf(“JCP Executive Committee”)
.setTwitter(“@kkzr”)
.setResponsibleFor(“Launcher”)
.build();
スピーカー
Copyright 2018 FUJITSU LIMITED
Speaker me = SpeakerBuilder
1
アジェンダ
Copyright 2018 FUJITSU LIMITED
GC問題
アプリケーションによる対処
コンパイラによる対処
サマリ
2
アジェンダ
Copyright 2018 FUJITSU LIMITED
GC問題
アプリケーションによる対処
コンパイラによる対処
サマリ
3
何が問題か
Copyright 2018 FUJITSU LIMITED
健康診断シンドローム
アプリケーションの実行が止まる
アプリケーションに割り当てられるCPU時間が減る
実はたいした問題ではない
4
スループット
レスポンス
なぜ問題か
Copyright 2018 FUJITSU LIMITED
(Cでは、malloc/free回数に依存)
チューニングがたいへん
最適解をみつけるのが難しい
環境が変わるとやりなおし
見積もりができない
GC時間は残存オブジェクトに依存
5
問題の対処方法
Copyright 2018 FUJITSU LIMITED
あきらめる SLAの妥協
Javaを使わない
オブジェクトの
生成数・量を減らす
アプリケーションで頑張る
GCで頑張る
コンパイラで頑張る
優秀なGCを作る
オブジェクトの
生成を最適化
6
デモ
Copyright 2018 FUJITSU LIMITED7
Node.js
$ node –trace-gc node.js
$ graalvm-ce-1.0.0-rc10/bin/node --jvm.Xmx16m --jvm.Xms16m --jvm.verbose:gc node.js
アジェンダ
Copyright 2018 FUJITSU LIMITED
GC問題
アプリケーションによる対処
コンパイラによる対処
サマリ
8
アプリケーションで頑張る
Copyright 2018 FUJITSU LIMITED
オブジェクトプール (キャッシュ)
スレッドプール
コネクションプール
小ネタ
ArrayList 拡張
String.intern()
Boxing/Unboxing
9
Integer AutoBoxing
Copyright 2018 FUJITSU LIMITED10
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
キャッシュの範囲はプロパティで指定可能
java.lang.Integer.IntegerCache.high
よく使われる範囲はIntegerオブジェクトの使いまわし
Integer.java
プーリングコスト
Copyright 2018 FUJITSU LIMITED
1*(メモリ割当+初期化) + p*GCp
n*(メモリ割当+初期化) + u*GCu
プーリング使用時
プーリング不使用時
n: トランザクション回数
p: プーリング使用時のGC回数
u: プーリング不使用時のGC回数
GCp: プーリング使用時の1回のGC時間
GCu: プーリング不使用時の1回のGC時間
p < u
GCp > GCu
初期化 < n*初期化
メモリ割当は問題にならない
11
一般的な傾向
Edenからのアロケーション
Copyright 2018 FUJITSU LIMITED
o = new Object();
bottom top end
lock(Eden);
top = top + size;
unlock(Eden);
Bump The Pointer
bottom top end
12
size
TLAB (Thread-Local Allocation Buffer)
Copyright 2018 FUJITSU LIMITED
スレッド1スレッド2
Eden領域をスレッドごとに分割して割当て
ロックが不要に
13
lock(Eden);
top = top + size;
unlock(Eden);
Fast Allocation
Copyright 2018 FUJITSU LIMITED
https://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf
only requiring around 10 native instructions
Memory Management in the Java
HotSpot Virtual Machine
Bump the Pointer + TLAB で実現
14
デモ
Copyright 2018 FUJITSU LIMITED15
Bump The Pointer
$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp -XX:CompileCommand=compileonly,Bump.doIt -XX:-UseTLAB Bump
$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp -XX:CompileCommand=compileonly,Bump.doIt Bump
(注)PrintAssemblyを使うには、hsdisが必要。https://github.com/liuzhengyang/hsdis
TLABが向かないケース
Copyright 2018 FUJITSU LIMITED
スレッド N+1 用のTLABが割当てられない
スレッド1スレッド2 スレッドN
・・・
スレッド数が多く、かつ、オブジェクト生成量が少ない場合
16
デモ
Copyright 2018 FUJITSU LIMITED17
Thread-Local Allocation Buffer
$ java -Xmx32m -Xms32m -verbose:gc TLAB
$ java -Xmx32m -Xms32m -verbose:gc -XX:-UseTLAB TLAB
アジェンダ
Copyright 2018 FUJITSU LIMITED
GC問題
アプリケーションによる対処
コンパイラによる対処
サマリ
18
デモ
Copyright 2018 FUJITSU LIMITED19
メモリアロケーション量とGC頻度
$ java -Xmx32m -Xms32m -verbose:gc EA
Escape Analysis (EA)
Copyright 2018 FUJITSU LIMITED
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/performance-
enhancements-7.html
JDK 6 (HotSpot C2) から採用
JITによる最適化
Scalar Replacement
Stack Allocation
Lock Elision
20
Escapeとは
Copyright 2018 FUJITSU LIMITED
メソッドからの脱出
オブジェクトがアロケートされたメソッドの外で
使用されているかもしれない
オブジェクトはメソッドローカルでない
スレッドからの脱出
オブジェクトがアロケートされたスレッドの外で
使用されているかもしれない
他のスレッドがそのオブジェクトにアクセスするかもしれない
21
Escapeの種類
Copyright 2018 FUJITSU LIMITED
オブジェクトはグローバルに脱出する
オブジェクトは作成したメソッドを脱出しない
オブジェクトは引数経由でメソッドを脱出するが、
スレッドは脱出しない
NoEscape
ArgEscape
GlobalEscape
22
Escapeの例
Copyright 2018 FUJITSU LIMITED
int foo(String name) {
Person person = new Person(name);
return person.id();
}
void foo(String name) {
Person person = new Person(name);
register(person);
}
NoEscape
ArgEscape
23
Escapeの例
Copyright 2018 FUJITSU LIMITED
class bar {
Person person;
void foo(String name) {
person = new Person(name);
}
}
GlobalEscape
24
最適化の組み合わせ
Copyright 2018 FUJITSU LIMITED
Scalar
Replacement
Stack
Allocation
Lock
Elision
No
Escape 〇 〇 〇
Arg
Escape - - 〇
Global
Escape - - -
25
Stack Allocation
Copyright 2018 FUJITSU LIMITED
オブジェクトをヒープではなくスタックにアロケートする
メソッド終了と同時にオブジェクトは解放
HotSpotでは不採用
26
Stack Allocation
Copyright 2018 FUJITSU LIMITED
ヘッダ
32
山田
太郎
SP
メソッド
開始時
new Person()
実行後
メソッド
終了時
残骸
SP
SP
27
void foo {
Person person = new Person(32, “山田太郎”);
・・・
スタック
Scalar Replacement
Copyright 2018 FUJITSU LIMITED
オブジェクトフィールドへのアクセスを、
スタックまたはレジスターアクセスにする
Stack Allocationとは異なり、
オブジェクトヘッダー等はアロケートされない
28
Scalar Replacement 例
Copyright 2018 FUJITSU LIMITED
int foo(String name, int age) {
Person person = new Person(name, age);
return person.getAge();
}
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
29
デモ
Copyright 2018 FUJITSU LIMITED30
Scalar Replacement
$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=print,ScalarReplace.doIt -XX:-DoEscapeAnalysis ScalarReplace
$ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=print,ScalarReplace.doIt -XX:+DoEscapeAnalysis ScalarReplace
$ java -verbose:gc -Xmx32m -Xms32m -XX:CompileCommand=dontinline,ScalarReplace.getPersonId ScalarReplace
Lock Elision
Copyright 2018 FUJITSU LIMITED
スレッドローカルなオブジェクトに対するロックを削除
31
void foo() {
Object lock = new Ojbect();
synchronized (lock) {
//doSomething
};
}
アジェンダ
Copyright 2018 FUJITSU LIMITED
GC問題
アプリケーションによる対処
コンパイラによる対処
サマリ
32
サマリ
Copyright 2018 FUJITSU LIMITED
GCの問題と対処
JVMの種類やインライン状況によっては、
GCが発生したり、しなかったり
33
まずは、見やすいコードを
GCは日々改善されている
Javaのアロケーションコストは低い
EAによるメモリ最適化もあり
Copyright 2018 FUJITSU LIMITED
Q/A
34
GCを発生させないJVMとコーディングスタイル

More Related Content

What's hot

オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)
オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)
オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)NTT DATA Technology & Innovation
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Etsuji Nakai
 
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本Takahiro YAMADA
 
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)NTT DATA Technology & Innovation
 
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応までDocker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応までMasahito Zembutsu
 
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...Shinji Takao
 
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26Yahoo!デベロッパーネットワーク
 
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)NTT DATA Technology & Innovation
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Masahito Zembutsu
 
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)Yoshiro Tokumasu
 
Java でつくる 低レイテンシ実装の技巧
Java でつくる低レイテンシ実装の技巧Java でつくる低レイテンシ実装の技巧
Java でつくる 低レイテンシ実装の技巧 Ryosuke Yamazaki
 
java.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷javajava.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷javaYuji Kubota
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使うKazuhiro Suga
 
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線Motonori Shindo
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門Kohei Tokunaga
 
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021Preferred Networks
 

What's hot (20)

オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)
オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)
オススメのJavaログ管理手法 ~コンテナ編~(Open Source Conference 2022 Online/Spring 発表資料)
 
Metaspace
MetaspaceMetaspace
Metaspace
 
golang profiling の基礎
golang profiling の基礎golang profiling の基礎
golang profiling の基礎
 
Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門Linux女子部 systemd徹底入門
Linux女子部 systemd徹底入門
 
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajpAt least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
 
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本
 
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
ストリーム処理におけるApache Avroの活用について(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019/09/05)
 
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応までDocker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
 
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
GraalVMのJavaネイティブビルド機能でどの程度起動が速くなるのか?~サーバレス基盤上での評価~ / How fast does GraalVM's...
 
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
Micrometer/Prometheusによる大規模システムモニタリング #jsug #sf_26
 
Docker Tokyo
Docker TokyoDocker Tokyo
Docker Tokyo
 
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
 
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
 
Java でつくる 低レイテンシ実装の技巧
Java でつくる低レイテンシ実装の技巧Java でつくる低レイテンシ実装の技巧
Java でつくる 低レイテンシ実装の技巧
 
java.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷javajava.lang.OutOfMemoryError #渋谷java
java.lang.OutOfMemoryError #渋谷java
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使う
 
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門
 
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021
PFNのML/DL基盤を支えるKubernetesにおける自動化 / DevOpsDays Tokyo 2021
 

Similar to GCを発生させないJVMとコーディングスタイル

Oracle code one 2018 報告会概要
Oracle code one 2018 報告会概要Oracle code one 2018 報告会概要
Oracle code one 2018 報告会概要Chihiro Ito
 
【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみた
【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみた【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみた
【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみたYuya Ohara
 
JavaOne 2016 Java SE Feedback #jjug #j1jp
JavaOne 2016 Java SE Feedback #jjug #j1jpJavaOne 2016 Java SE Feedback #jjug #j1jp
JavaOne 2016 Java SE Feedback #jjug #j1jpYuji Kubota
 
Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -
Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -
Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -Yahoo!デベロッパーネットワーク
 
Microprofileでエンタープライズ品質
Microprofileでエンタープライズ品質Microprofileでエンタープライズ品質
Microprofileでエンタープライズ品質Kenji Kazumura
 
Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例
Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例
Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例Hironobu Isoda
 
RICOH THETA プラグイン開発 ワークショップ #1
RICOH THETA プラグイン開発 ワークショップ #1RICOH THETA プラグイン開発 ワークショップ #1
RICOH THETA プラグイン開発 ワークショップ #1RICOHTHETAPluginDevloperCommunity
 
(Tech DeepDive #1) Java Flight Recorder を活用した問題解決
(Tech DeepDive #1) Java Flight Recorder を活用した問題解決(Tech DeepDive #1) Java Flight Recorder を活用した問題解決
(Tech DeepDive #1) Java Flight Recorder を活用した問題解決オラクルエンジニア通信
 
Git超入門_座学編.pdf
Git超入門_座学編.pdfGit超入門_座学編.pdf
Git超入門_座学編.pdf憲昭 村田
 
GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)
GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)
GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)NTT DATA Technology & Innovation
 
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)NTT DATA Technology & Innovation
 
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組みJJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み日本Javaユーザーグループ
 
5月中旬の仮想通貨Re-orgについて
5月中旬の仮想通貨Re-orgについて5月中旬の仮想通貨Re-orgについて
5月中旬の仮想通貨Re-orgについてMasanori Kusunoki
 
Introduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVMIntroduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVMKoichi Sakata
 
こんな辛いテストはいやだ
こんな辛いテストはいやだ こんな辛いテストはいやだ
こんな辛いテストはいやだ Takuya Mikami
 
Java 10でぼくたちの生活はどう変わるの?
Java 10でぼくたちの生活はどう変わるの?Java 10でぼくたちの生活はどう変わるの?
Java 10でぼくたちの生活はどう変わるの?Yuji Kubota
 
RETEアルゴリズムを使いこなせ
RETEアルゴリズムを使いこなせRETEアルゴリズムを使いこなせ
RETEアルゴリズムを使いこなせMasahiko Umeno
 
JavaOne 2015 JDK Update (Jigsaw) #j1jp
JavaOne 2015 JDK Update (Jigsaw) #j1jpJavaOne 2015 JDK Update (Jigsaw) #j1jp
JavaOne 2015 JDK Update (Jigsaw) #j1jpYuji Kubota
 

Similar to GCを発生させないJVMとコーディングスタイル (20)

Oracle code one 2018 報告会概要
Oracle code one 2018 報告会概要Oracle code one 2018 報告会概要
Oracle code one 2018 報告会概要
 
【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみた
【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみた【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみた
【GCP】DDoS対策 Cloud Armor(クラウドアーマー)を試してみた
 
JavaOne 2016 Java SE Feedback #jjug #j1jp
JavaOne 2016 Java SE Feedback #jjug #j1jpJavaOne 2016 Java SE Feedback #jjug #j1jp
JavaOne 2016 Java SE Feedback #jjug #j1jp
 
Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -
Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -
Yahoo! JAPANのデータパイプラインで起きた障害とチューニング - Apache Kafka Meetup Japan #5 -
 
CPUから見たG1GC
CPUから見たG1GCCPUから見たG1GC
CPUから見たG1GC
 
Microprofileでエンタープライズ品質
Microprofileでエンタープライズ品質Microprofileでエンタープライズ品質
Microprofileでエンタープライズ品質
 
Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例
Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例
Logicadの秒間16万リクエストをさばく広告入札システムにおける、gRPCの活用事例
 
RICOH THETA プラグイン開発 ワークショップ #1
RICOH THETA プラグイン開発 ワークショップ #1RICOH THETA プラグイン開発 ワークショップ #1
RICOH THETA プラグイン開発 ワークショップ #1
 
(Tech DeepDive #1) Java Flight Recorder を活用した問題解決
(Tech DeepDive #1) Java Flight Recorder を活用した問題解決(Tech DeepDive #1) Java Flight Recorder を活用した問題解決
(Tech DeepDive #1) Java Flight Recorder を活用した問題解決
 
Git超入門_座学編.pdf
Git超入門_座学編.pdfGit超入門_座学編.pdf
Git超入門_座学編.pdf
 
GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)
GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)
GraalVMでのFlight Recorderを使ったパフォーマンス解析(JJUG CCC 2023 Spring)
 
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
より速く より運用しやすく 進化し続けるJVM(Java Developers Summit Online 2023 発表資料)
 
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組みJJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
JJavaプログラム実行の仕組みと、高速・安定動作に向けた取り組み
 
5月中旬の仮想通貨Re-orgについて
5月中旬の仮想通貨Re-orgについて5月中旬の仮想通貨Re-orgについて
5月中旬の仮想通貨Re-orgについて
 
Kubernetes Cluster Adminやってました #con_rider
Kubernetes Cluster Adminやってました #con_riderKubernetes Cluster Adminやってました #con_rider
Kubernetes Cluster Adminやってました #con_rider
 
Introduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVMIntroduction to JIT Compiler in JVM
Introduction to JIT Compiler in JVM
 
こんな辛いテストはいやだ
こんな辛いテストはいやだ こんな辛いテストはいやだ
こんな辛いテストはいやだ
 
Java 10でぼくたちの生活はどう変わるの?
Java 10でぼくたちの生活はどう変わるの?Java 10でぼくたちの生活はどう変わるの?
Java 10でぼくたちの生活はどう変わるの?
 
RETEアルゴリズムを使いこなせ
RETEアルゴリズムを使いこなせRETEアルゴリズムを使いこなせ
RETEアルゴリズムを使いこなせ
 
JavaOne 2015 JDK Update (Jigsaw) #j1jp
JavaOne 2015 JDK Update (Jigsaw) #j1jpJavaOne 2015 JDK Update (Jigsaw) #j1jp
JavaOne 2015 JDK Update (Jigsaw) #j1jp
 

More from Kenji Kazumura

Jakarta EE 9 と これから
Jakarta EE 9 と これからJakarta EE 9 と これから
Jakarta EE 9 と これからKenji Kazumura
 
JakartaOne Livestream Japan 2020
JakartaOne Livestream Japan 2020JakartaOne Livestream Japan 2020
JakartaOne Livestream Japan 2020Kenji Kazumura
 
Versatil Javaチューニング
Versatil JavaチューニングVersatil Javaチューニング
Versatil JavaチューニングKenji Kazumura
 
Challenge for GlassFish Builpack
Challenge for GlassFish BuilpackChallenge for GlassFish Builpack
Challenge for GlassFish BuilpackKenji Kazumura
 
Python + GDB = Javaデバッガ
Python + GDB = JavaデバッガPython + GDB = Javaデバッガ
Python + GDB = JavaデバッガKenji Kazumura
 
JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]Kenji Kazumura
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うKenji Kazumura
 

More from Kenji Kazumura (8)

Jakarta EE 9 と これから
Jakarta EE 9 と これからJakarta EE 9 と これから
Jakarta EE 9 と これから
 
JakartaOne Livestream Japan 2020
JakartaOne Livestream Japan 2020JakartaOne Livestream Japan 2020
JakartaOne Livestream Japan 2020
 
Versatil Javaチューニング
Versatil JavaチューニングVersatil Javaチューニング
Versatil Javaチューニング
 
microprofile
microprofilemicroprofile
microprofile
 
Challenge for GlassFish Builpack
Challenge for GlassFish BuilpackChallenge for GlassFish Builpack
Challenge for GlassFish Builpack
 
Python + GDB = Javaデバッガ
Python + GDB = JavaデバッガPython + GDB = Javaデバッガ
Python + GDB = Javaデバッガ
 
JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使う
 

GCを発生させないJVMとコーディングスタイル

  • 2. .setName(“数村憲治”) .setDirectorOf(“Eclipse Foundation Board”) .setMemberOf(“Jakarta EE Committee”) .setMemberOf(“JCP Executive Committee”) .setTwitter(“@kkzr”) .setResponsibleFor(“Launcher”) .build(); スピーカー Copyright 2018 FUJITSU LIMITED Speaker me = SpeakerBuilder 1
  • 3. アジェンダ Copyright 2018 FUJITSU LIMITED GC問題 アプリケーションによる対処 コンパイラによる対処 サマリ 2
  • 4. アジェンダ Copyright 2018 FUJITSU LIMITED GC問題 アプリケーションによる対処 コンパイラによる対処 サマリ 3
  • 5. 何が問題か Copyright 2018 FUJITSU LIMITED 健康診断シンドローム アプリケーションの実行が止まる アプリケーションに割り当てられるCPU時間が減る 実はたいした問題ではない 4 スループット レスポンス
  • 6. なぜ問題か Copyright 2018 FUJITSU LIMITED (Cでは、malloc/free回数に依存) チューニングがたいへん 最適解をみつけるのが難しい 環境が変わるとやりなおし 見積もりができない GC時間は残存オブジェクトに依存 5
  • 7. 問題の対処方法 Copyright 2018 FUJITSU LIMITED あきらめる SLAの妥協 Javaを使わない オブジェクトの 生成数・量を減らす アプリケーションで頑張る GCで頑張る コンパイラで頑張る 優秀なGCを作る オブジェクトの 生成を最適化 6
  • 8. デモ Copyright 2018 FUJITSU LIMITED7 Node.js $ node –trace-gc node.js $ graalvm-ce-1.0.0-rc10/bin/node --jvm.Xmx16m --jvm.Xms16m --jvm.verbose:gc node.js
  • 9. アジェンダ Copyright 2018 FUJITSU LIMITED GC問題 アプリケーションによる対処 コンパイラによる対処 サマリ 8
  • 10. アプリケーションで頑張る Copyright 2018 FUJITSU LIMITED オブジェクトプール (キャッシュ) スレッドプール コネクションプール 小ネタ ArrayList 拡張 String.intern() Boxing/Unboxing 9
  • 11. Integer AutoBoxing Copyright 2018 FUJITSU LIMITED10 public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } キャッシュの範囲はプロパティで指定可能 java.lang.Integer.IntegerCache.high よく使われる範囲はIntegerオブジェクトの使いまわし Integer.java
  • 12. プーリングコスト Copyright 2018 FUJITSU LIMITED 1*(メモリ割当+初期化) + p*GCp n*(メモリ割当+初期化) + u*GCu プーリング使用時 プーリング不使用時 n: トランザクション回数 p: プーリング使用時のGC回数 u: プーリング不使用時のGC回数 GCp: プーリング使用時の1回のGC時間 GCu: プーリング不使用時の1回のGC時間 p < u GCp > GCu 初期化 < n*初期化 メモリ割当は問題にならない 11 一般的な傾向
  • 13. Edenからのアロケーション Copyright 2018 FUJITSU LIMITED o = new Object(); bottom top end lock(Eden); top = top + size; unlock(Eden); Bump The Pointer bottom top end 12 size
  • 14. TLAB (Thread-Local Allocation Buffer) Copyright 2018 FUJITSU LIMITED スレッド1スレッド2 Eden領域をスレッドごとに分割して割当て ロックが不要に 13 lock(Eden); top = top + size; unlock(Eden);
  • 15. Fast Allocation Copyright 2018 FUJITSU LIMITED https://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf only requiring around 10 native instructions Memory Management in the Java HotSpot Virtual Machine Bump the Pointer + TLAB で実現 14
  • 16. デモ Copyright 2018 FUJITSU LIMITED15 Bump The Pointer $ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp -XX:CompileCommand=compileonly,Bump.doIt -XX:-UseTLAB Bump $ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -Xcomp -XX:CompileCommand=compileonly,Bump.doIt Bump (注)PrintAssemblyを使うには、hsdisが必要。https://github.com/liuzhengyang/hsdis
  • 17. TLABが向かないケース Copyright 2018 FUJITSU LIMITED スレッド N+1 用のTLABが割当てられない スレッド1スレッド2 スレッドN ・・・ スレッド数が多く、かつ、オブジェクト生成量が少ない場合 16
  • 18. デモ Copyright 2018 FUJITSU LIMITED17 Thread-Local Allocation Buffer $ java -Xmx32m -Xms32m -verbose:gc TLAB $ java -Xmx32m -Xms32m -verbose:gc -XX:-UseTLAB TLAB
  • 19. アジェンダ Copyright 2018 FUJITSU LIMITED GC問題 アプリケーションによる対処 コンパイラによる対処 サマリ 18
  • 20. デモ Copyright 2018 FUJITSU LIMITED19 メモリアロケーション量とGC頻度 $ java -Xmx32m -Xms32m -verbose:gc EA
  • 21. Escape Analysis (EA) Copyright 2018 FUJITSU LIMITED https://docs.oracle.com/javase/8/docs/technotes/guides/vm/performance- enhancements-7.html JDK 6 (HotSpot C2) から採用 JITによる最適化 Scalar Replacement Stack Allocation Lock Elision 20
  • 22. Escapeとは Copyright 2018 FUJITSU LIMITED メソッドからの脱出 オブジェクトがアロケートされたメソッドの外で 使用されているかもしれない オブジェクトはメソッドローカルでない スレッドからの脱出 オブジェクトがアロケートされたスレッドの外で 使用されているかもしれない 他のスレッドがそのオブジェクトにアクセスするかもしれない 21
  • 23. Escapeの種類 Copyright 2018 FUJITSU LIMITED オブジェクトはグローバルに脱出する オブジェクトは作成したメソッドを脱出しない オブジェクトは引数経由でメソッドを脱出するが、 スレッドは脱出しない NoEscape ArgEscape GlobalEscape 22
  • 24. Escapeの例 Copyright 2018 FUJITSU LIMITED int foo(String name) { Person person = new Person(name); return person.id(); } void foo(String name) { Person person = new Person(name); register(person); } NoEscape ArgEscape 23
  • 25. Escapeの例 Copyright 2018 FUJITSU LIMITED class bar { Person person; void foo(String name) { person = new Person(name); } } GlobalEscape 24
  • 26. 最適化の組み合わせ Copyright 2018 FUJITSU LIMITED Scalar Replacement Stack Allocation Lock Elision No Escape 〇 〇 〇 Arg Escape - - 〇 Global Escape - - - 25
  • 27. Stack Allocation Copyright 2018 FUJITSU LIMITED オブジェクトをヒープではなくスタックにアロケートする メソッド終了と同時にオブジェクトは解放 HotSpotでは不採用 26
  • 28. Stack Allocation Copyright 2018 FUJITSU LIMITED ヘッダ 32 山田 太郎 SP メソッド 開始時 new Person() 実行後 メソッド 終了時 残骸 SP SP 27 void foo { Person person = new Person(32, “山田太郎”); ・・・ スタック
  • 29. Scalar Replacement Copyright 2018 FUJITSU LIMITED オブジェクトフィールドへのアクセスを、 スタックまたはレジスターアクセスにする Stack Allocationとは異なり、 オブジェクトヘッダー等はアロケートされない 28
  • 30. Scalar Replacement 例 Copyright 2018 FUJITSU LIMITED int foo(String name, int age) { Person person = new Person(name, age); return person.getAge(); } class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } } 29
  • 31. デモ Copyright 2018 FUJITSU LIMITED30 Scalar Replacement $ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=print,ScalarReplace.doIt -XX:-DoEscapeAnalysis ScalarReplace $ java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=print,ScalarReplace.doIt -XX:+DoEscapeAnalysis ScalarReplace $ java -verbose:gc -Xmx32m -Xms32m -XX:CompileCommand=dontinline,ScalarReplace.getPersonId ScalarReplace
  • 32. Lock Elision Copyright 2018 FUJITSU LIMITED スレッドローカルなオブジェクトに対するロックを削除 31 void foo() { Object lock = new Ojbect(); synchronized (lock) { //doSomething }; }
  • 33. アジェンダ Copyright 2018 FUJITSU LIMITED GC問題 アプリケーションによる対処 コンパイラによる対処 サマリ 32
  • 34. サマリ Copyright 2018 FUJITSU LIMITED GCの問題と対処 JVMの種類やインライン状況によっては、 GCが発生したり、しなかったり 33 まずは、見やすいコードを GCは日々改善されている Javaのアロケーションコストは低い EAによるメモリ最適化もあり
  • 35. Copyright 2018 FUJITSU LIMITED Q/A 34