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
【JUGナイトセミナー】検証では成功した Java のパッチが商用でコケた件
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Takaichi00
August 26, 2020
Technology
490
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
【JUGナイトセミナー】検証では成功した Java のパッチが商用でコケた件
Takaichi00
August 26, 2020
More Decks by Takaichi00
See All by Takaichi00
individual_or_organization
takaichi00
0
290
自分から始めるアジャイルの道 ~内発的動機をきっかけに変わった価値観~
takaichi00
0
460
Java developer introduced to Rust-ADC2022
takaichi00
0
310
野球人・落合博満さんから学ぶ、アジャイルなマインドセット・プラクティス
takaichi00
1
910
【CICD2021】デプロイメントパイプラインの原理原則を再確認する / Confirm Deployment Pipeline Principle
takaichi00
11
4.7k
【JTF2021】SonarQube をより有効活用する / Effective SonarQube
takaichi00
1
2.7k
JJUG CCC 2021 Spring-Resolving OOME with JFR
takaichi00
2
3.8k
【Yahoo! JAPAN Agile 2nd】野球人・落合博満さんから学ぶスクラムマスター / デベロッパー
takaichi00
0
2.8k
【Developers Boost 2020】凡人エンジニアの生存戦略
takaichi00
1
3.3k
Other Decks in Technology
See All in Technology
Kiro Ambassador を目指す話
k_adachi_01
0
110
LayerX コーポレートエンジニアリング室におけるサプライチェーンセキュリティへの取り組み / Supply Chain Security at LayerX Corporate Engineering
yuyatakeyama
2
680
失敗を資産に変えるClaude Code
shinyasaita
0
720
脱SaaS!FDEを支えるプロビジョニングと分離設計
knih
0
240
【NRUG vol.18】KubernetesにおけるNew Relicデータ取得量削減の考え方
nrug_member
0
170
Kiroで書いた 設計書 が AI レビューの 採点基準 になる
ezaki
0
130
攻撃者視点で考えるDetection Engineering
cryptopeg
3
2k
AI-DLCを “そのまま導入しなかった”話 ~組織に合わせてアジャストした 私たちの実践共有~
hiroramos4
PRO
0
210
自宅LLMの話
jacopen
1
660
AI時代のコスト管理を考えよう〜明日から使える実践AWSノウハウ~
yoshimi0227
0
310
2026TECHFRESH畢業分享會 - 葬送的通靈師:化系統與用戶雜訊成行動訊號
line_developers_tw
PRO
0
1.3k
【セミナー資料】Claude Code をセキュアに使うための考え方と設定の勘どころ / Claude Code Webinar 20260616
masahirokawahara
2
420
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
100
6.2k
First, design no harm
axbom
PRO
2
1.2k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
170
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
460
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
Odyssey Design
rkendrick25
PRO
2
700
The SEO Collaboration Effect
kristinabergwall1
1
490
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Building AI with AI
inesmontani
PRO
1
1.1k
Are puppies a ranking factor?
jonoalderson
1
3.6k
A Soul's Torment
seathinner
6
3k
Everyday Curiosity
cassininazir
0
230
Transcript
検証では成功した Java のパッチが商用でコケた件 #JJUG 髙市 智章 (Tomoaki Takaichi) Aug, 26,
2020 【オンライン】 JJUGナイトセミナー「おうちで!ビール片手にLT大会!」
自己紹介 @Takaichi00 tomoaki.takaichi.5 ・髙市 智章(タカイチ トモアキ) ・Java / Node でのシステム開発
・CI / CD ・Container / k8s ・アジャイル開発実践 共著: クリーンなコードへの SonarQube即効活用術 http://u0u0.net/RSvx
本日お話すること ❏ 以前、検証では成功した Java のプログラムが商用で失敗 するということを経験した ❏ Java 初心者の方や教育されている方に、プログラミング 言語として
Java を知っているだけでは痛い目にあってし まうという一例になれば ※ 内容は発表に向けてカスタマイズしています
❏ 以下のような java のプログラムを作成したかった やりたかったこと id name address 1 aaa
NULL 2 bbb NULL ... … ... name register_ event aaa 1 aaa 2 bbb 1 .jar ① `address` が NULL の一覧取得 ② `name` に対応する `register_event` を取得 / 判定処理 insert.sql ④ TABLE_A に `name` に対 応する `address` を insert する SQL ファイルを作成 TABLE_A TABLE_B register_ event address 1 123 2 456 ... ... TABLE_C ③ `register_event` に対応する `address` を取得 / 判定処理
❏ 実装したプログラムの概要は以下の通り 問題の実装コードと実行コマンド public static void main(String[] args) throws SQLException
{ List<UpdateAttribute> updateAttributes = null; try (Connection con = DriverManager.getConnection(connectionUrl, "user", "pass")) { updateAttributes = new ArrayList<>(); String sql1 = "SELECT id,name,address FROM TABLE_A WHERE address is NULL"; PreparedStatement stmt1 = con.prepareStatement(sql1); ResultSet rs1 = stmt1.executeQuery(sql1); // SELECT したすべてのデータを List に格納 while (rs1.next()) { updateAttributes.add(new UpdateAttribute(rs1.getInt("id"), rs1.getString("name"), null)); } for (UpdateAttribute updateAttribute : updateAttributes) { // List をループして更に別テーブルに SELECT 文を実行 while (rs2.next()) { // なんらかの業務ロジック … 省略 } public static void main(String[] args) throws SQLException { … 省略 for (UpdateAttribute updateAttribute : updateAttributes) { // List をループして更に別テーブルに SELECT 文を実行 while (rs2.next()) { // なんらかの業務ロジック ... String sql3 = "SELECT name,address FROM TABLE_B WHERE name='" + <ロジックから取得できた値> + "'"; while (rs3.next()) { // なんらかの業務ロジック ... updateAttribute.setAddress(rs3.getString("address")); } } } // SQL ファイル出力処理 ... } catch () … // 例外処理 }
❏ 複数回実行されていた PreparedStatement や ResultSet は それぞれ close されていなかった ❏
SELECT 文で取得できた ResultSet の結果を List に一括代入 ❏ 実行する際は起動オプションを指定せず、単純に「java -jar ~~.jar」と実行 問題の実装コードと実行コマンド
❏ ローカル PC (メモリ 16GB) から、検証用のデータが入っ た検証用 DB へ向けてこのパッチを起動したところ、問題 なく実行が完了した
(データ量は数十件程度) 検証の構成では成功 検証環境 成功 メモリ: 16GB
❏ 商用環境では VM 上 (メモリ 1GB) で作成したパッチを実 行した。しかし処理が全然完了しなかった ❏ 商用のデータ量は検証環境よりは多いが、たかだか1万件
未満程度のもの 商用環境では失敗 商用環境 失敗 メモリ: 1GB
❏ java -jar コマンド実行時の引数に -Xlog:gc* を追加して GC ログの詳細を表示してみる ❏ すると
FullGC が多発していることがわかった GC ログを出してみる $ java -Xlog:gc* -jar hoge.jar ... [81.318s][info][gc ] GC(29) Pause Full (G1 Evacuation Pause) ... [81.318s][info][gc,cpu ] GC(29) User=0.05s Sys=0.00s Real=0.02s
❏ JVM にはエルゴノミクスというプロセスがあり、マシンの スペックに応じてヒープサイズが自動決定される ❏ デフォルトでは以下の設定となっている ヒープオプションを追加する 初期ヒープ・サイズ 物理メモリーの 1/64
(最大1GB) 最大ヒープ・サイズ 物理メモリの 1/4 (最大1GB) ❏ jar 実行時に、-Xms512M -Xmx512M のようにヒープサ イズを設定することで、時間はかかったが処理を完了させ ることができた
⇒ 検証するため、再度似たようなプログラムを作成して GC Viewer を用いて解析をしてみる ❏ 仮説1: PreparedStatement / ResultSet
の close 忘れ ❏ 仮説2: 最初に SELECT で一気にテーブルの値を List に格 納してしまったことでヒープサイズを圧迫 そもそも実装コードが悪い
❏ 似たようなプログラムをヒープサイズを指定し、GC ログを 出力するようにして実行した結果、処理が進むに連れ FullGC が発生して最終的に OOME が発生した (データ量約1万件) 問題のプログラムを解析する
$ java -Xlog:gc:./gc.log \ -Xlog:gc* \ -Xms20M -Xmx20M -jar hoge.jar
❏ PreparedStatement / ResultSet を close するよう処理 を修正したところ FullGC は発生せず適切にメモリが開放
されて処理が継続できた (データ量約1万件) 仮説1: PreparedStatement / ResultSet の close 忘れ
❏ close 処理を実施し、データ件数を1万件から2万件に変更し て実行したが、初期のヒープサイズがやや増加したのみ。 よって今回ではクリティカルな問題ではなかった。 仮説2: List に全件のデータを格納してしまった
まとめ ❏ ヒープサイズは指定するようにする (エルゴノミクス) ❏ close 処理を怠らない ❏ DB からデータを取得して
Java メモリ上に大量のデータ を格納するような処理はしない ❏ GC ログや GC Viewer の利用方法を知っておくと便利 ❏ できるなら商用環境のデータ量でテストを実施する
まとめ ❏ 今回ではプログラミング言語として Java を知っているだ けでは痛い目にあうという一例を紹介した ❏ Java をこれから始めようとされている方 /
Java を教えて いる方などの参考になれば幸いです
❏ エルゴノミクス (Oracle 公式) ❏ Java開発の性能改善! その2 GCログの解析とHeapの設定 ❏ JavaのGCの仕組みを整理する
❏ JavaのGCに関するオプションについてまとめてみた。 ❏ JVM入門 -Javaプログラムが動く仕組み- ❏ Statement の解放漏れには気をつけよう ❏ MySQL Connector/J (JDBC ドライバ)の罠まとめ ❏ MySQL+Connector/Jを使って、大量データのSELECT⇒INSERTした時の挙動を確認する ❏ JDBC setFetchSize() ではまった話 ❏ JDBC経由で100万件取得・追加してみた ❏ Java いまふたたびのJDBC 参考文献
ご清聴ありがとうございました