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
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
300
自分から始めるアジャイルの道 ~内発的動機をきっかけに変わった価値観~
takaichi00
0
470
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
10年目を迎えた「ABEMA」がどのように AI 活用を推進して、AI 駆動開発にシフトしているのか / How ABEMA, entering its 10th year, is promoting the use of AI and shifting toward AI-driven development
miyukki
0
130
[2026-07-15] AI Ready なはずだったアーキテクチャと、見えてきた課題・次に目指す状態
wxyzzz
4
2.8k
CIで使うClaude
iwatatomoya
0
250
プロダクトだけじゃない、社内プロセスにおける自動化・省力化ノススメ
kakehashi
PRO
1
3.7k
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.4k
オブザーバビリティ、本当に活用できてる? 〜API連携×生成AIで成熟度を自動評価〜
dmmsre
1
3.1k
公式ドキュメントの歩き方etc
coco_se
0
100
SRE本の知られざる名シーン / The Hidden Gems of Google SRE Book
nari_ex
1
380
穢れた技術選定について
watany
4
370
AI時代のエンジニアキャリアについて今一度考える
sakamoto_582
2
1.5k
ZOZOTOWNの進化と信頼性を両立する負荷試験
zozotech
PRO
2
160
「最後に責任を取るのはチーム」— 人間のPRレビューを最小化してアップデートしたメンタルモデル
jnishime_dresscode
0
600
Featured
See All Featured
A Tale of Four Properties
chriscoyier
163
24k
Prompt Engineering for Job Search
mfonobong
0
370
WCS-LA-2024
lcolladotor
0
680
Chasing Engaging Ingredients in Design
codingconduct
0
230
Site-Speed That Sticks
csswizardry
13
1.2k
How to train your dragon (web standard)
notwaldorf
97
6.7k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
220
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
190
Navigating Weather and Climate Data
rabernat
0
310
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
ラッコキーワード サービス紹介資料
rakko
1
3.9M
We Have a Design System, Now What?
morganepeng
55
8.2k
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 参考文献
ご清聴ありがとうございました