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
340
自分から始めるアジャイルの道 ~内発的動機をきっかけに変わった価値観~
takaichi00
0
480
Java developer introduced to Rust-ADC2022
takaichi00
0
310
野球人・落合博満さんから学ぶ、アジャイルなマインドセット・プラクティス
takaichi00
1
930
【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
長期運営で肥大化したExcelマスターデータの解消に向けた移行事例
gree_tech
PRO
0
510
Master Dataグループ紹介資料
sansan33
PRO
1
4.8k
The Django UUID Story - DjangoCon US 2026
pauloxnet
0
260
dbt と Snowflake と tag
kevinrobot34
1
250
会計事務所と顧問先の契約関係をOIDC・OAuthで表現する
terara
0
330
AIで変わるエンジニアの働き方(仮)
naoinaoi
0
540
ClaudeCodeでセキュリティ監視業務を半自動化_1年の運用でわかったAIに任せる設計の5つのポイント
kintotechdev
2
300
Bill One 開発エンジニア 紹介資料
sansan33
PRO
7
20k
EUDIWの枠組みを出発点に民間エコシステムの在り方を考える(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
260
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.2k
コミュニティから始まった農業IoTとの7年間 ——人との関わりが教えてくれたこと
peacemaker07
0
110
「ミスを許さない手順書」を作ってみた 〜 個人的にはこれ以上できることはあまりなさそう/20260827-ssmjp-operation-procedure-update
opelab
1
210
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
A designer walks into a library…
pauljervisheath
211
24k
Docker and Python
trallard
47
4.1k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.3k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Navigating Weather and Climate Data
rabernat
0
490
Designing for Performance
lara
611
70k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.9k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
250
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 参考文献
ご清聴ありがとうございました