Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
【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
350
自分から始めるアジャイルの道 ~内発的動機をきっかけに変わった価値観~
takaichi00
0
490
Java developer introduced to Rust-ADC2022
takaichi00
0
310
野球人・落合博満さんから学ぶ、アジャイルなマインドセット・プラクティス
takaichi00
1
930
【CICD2021】デプロイメントパイプラインの原理原則を再確認する / Confirm Deployment Pipeline Principle
takaichi00
11
4.8k
【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.4k
Other Decks in Technology
See All in Technology
アプリログインとWeb認証基盤をつなぐ ASWebAuthenticationSession 作法
shimastripe
1
310
すぐできる衛星通信対応 あとは山奥に行くだけ
tatetate55
0
120
2026-09-09 【sigma_ucj#1】Sigma を IaC 管理したい! / IaC for Sigma
civitaspo
0
130
OpenTelemetry eBPF Instrumentationの舞台裏 / Behind the Scenes of OpenTelemetry eBPF Instrumentation
ymotongpoo
4
1.2k
Genieを崇めよ
kameitomohiro
0
120
銀行勘定系システムにおける開発プロセス刷新×AIによる環境モダナイゼーション / Development Process Transformation and AI-Driven Environment Modernization
muit
0
1.7k
AIを活用するために決めた "やらないこと" - 価値に注目する / Not betting on AI
soudai
PRO
1
500
20260912_スクラムにジェネラリストは必要か
ryugen04
0
400
[2026-09-11]SREは誰のもの?運用エンジニアが始める 「SRE領域への越境」とチームの進化の軌跡 〜Road to NEXT CRE
tosite
0
220
人間はどの意思決定を手放せるのか
kawasima
14
5.7k
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
1
1.3k
DEFCON_CHV_CTF_Write-up.pdf
bata_24
0
150
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
540
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
How to make the Groovebox
asonas
2
2.4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Designing for Timeless Needs
cassininazir
1
470
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.9k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.3k
KATA
mclloyd
PRO
35
15k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
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 参考文献
ご清聴ありがとうございました