内容紹介
JVMのチューニングと正しいプログラミングの両面からアプローチ!
本書ではJVMのチューニングとJavaプラットフォームでの問題解決の双方からJavaパフォーマンスの「アート」と「サイエンス」を明らかにします。Javaアプリケーションのテスト手法やベンチマーク測定、パフォーマンス分析に必須のモニタリングツールを学んだうえで、さまざまな性能改善について議論します。JITコンパイル、ガベージコレクションというチューニングが大きな役割を果たす2つの仕組みについて最初に考察します。続いて、Javaプラットフォームのさまざまな側面で高いパフォーマンスを発揮するためのベストプラクティスを紹介します。具体的には、Javaのヒープメモリ、ネイティブメモリ、スレッド、Java EEのAPI、JPAとJDBC、そしてJava SEのAPIでのヒントを取り上げます。
このような方におすすめ
Java開発者全般(組み込み、Web、サーバー、ネットワーク、データベース、大規模システムなど)
ィスト
・学生や研究者層
目次
詳細目次
監訳者まえがき
まえがき
1章 イントロダクション
1.1 概要
1.2 プラットフォームの呼称について
1.2.1 JVMのチューニングフラグ
1.3 パフォーマンスの全体像
1.3.1 よりよいアルゴリズムを記述する
1.3.2 コードの量を少なくする
1.3.3 早まった安易な最適化
1.3.4 外部を見渡す(データベースは常にボトルネック)
1.3.5 よくあるケースのために最適化する
1.4 まとめ
2章 パフォーマンステストのアプローチ
2.1 実アプリケーションでテストする
2.1.1 マイクロベンチマーク
2.1.2 マクロベンチマーク
2.1.3 メゾベンチマーク
2.1.4 本書で利用するサンプルコード
2.2 スループット、バッチ、レスポンスタイムを理解する
2.2.1 バッチ(一括)処理の測定
2.2.2 スループットの計測
2.2.3 レスポンスタイムのテスト
2.3 不安定性を理解する
2.4 早期から頻繁にテストを行う
2.5 まとめ
3章 Javaパフォーマンスのツールボックス
3.1 オペレーティングシステム付属のツールと分析
3.1.1 CPUの使用率
3.1.2 CPUのランキュー
3.1.3 ディスクの使用率
3.1.4 ネットワークの使用率
3.2 Javaの監視ツール
3.2.1 JVMの基本的な情報
3.2.2 スレッドの情報
3.2.3 クラスの情報
3.2.4 ガベージコレクションの動的な分析
3.2.5 ヒープダンプの事後的な分析
3.3 プロファイリングツール
3.3.1 サンプリング型のプロファイラ
3.3.2 instrumented型のプロファイラ
3.3.3 ブロックされたメソッドとスレッドのタイムライン
3.3.4 ネイティブなプロファイラ
3.4 Java Mission Control
3.4.1 JFR
3.4.2 JFRの有効化
3.4.3 JFRのイベントの選択
3.5 まとめ
4章 JITコンパイラのしくみ
4.1 JITコンパイラの概要
4.1.1 ホットスポットのコンパイル
4.2 基本的なチューニング(クライアントコンパイラとサーバーコンパイラ)
4.2.1 起動処理の最適化
4.2.2 バッチ処理の最適化
4.2.3 長時間実行されるアプリケーションの最適化
4.3 JavaとJITコンパイラのバージョン
4.4 中級のチューニング
4.4.1 コードキャッシュのチューニング
4.4.2 コンパイルのしきい値
4.4.3 コンパイルのプロセスを検証する
4.5 上級のチューニング
4.5.1 コンパイラのスレッド
4.5.2 インライン化
4.5.3 エスケープ分析
4.6 非最適化
4.6.1 entrantではないコード
4.6.2 ゾンビのコード
4.7 階層的コンパイルのレベル
4.8 まとめ
5章 ガベージコレクションの基礎
5.1 ガベージコレクションの概要
5.1.1 世代に基づくガベージコレクター
5.1.2 ガベージコレクションのアルゴリズム
5.1.3 ガベージコレクションのアルゴリズムの選択
5.2 ガベージコレクターの基本的なチューニング
5.2.1 ヒープサイズの変更
5.2.2 各領域のサイズ設定
5.2.3 permanent領域とメタスペースのサイズ変更
5.2.4 並列度の指定
5.2.5 adaptive sizing
5.3 ガベージコレクション関連のツール
5.4 まとめ
6章 ガベージコレクションのアルゴリズム
6.1 スループット型ガベージコレクターを理解する
6.1.1 適応的あるいは静的なヒープサイズのチューニング
6.2 CMSガベージコレクターを理解する
6.2.1 concurrent mode failureを回避するためのチューニング
6.2.2 permanent領域のためのCMSのチューニング
6.2.3 iCMS
6.3 G1ガベージコレクターを理解する
6.3.1 G1のチューニング
6.4 高度なチューニング
6.4.1 昇格とsurvivor空間
6.4.2 大きなオブジェクトの割り当て
6.4.3 AggressiveHeap
6.4.4 ヒープサイズの完全な制御
6.5 まとめ
7章 ヒープのベストプラクティス
7.1 ヒープの分析
7.1.1 ヒープヒストグラム
7.1.2 ヒープダンプ
7.1.3 OutOfMemoryError
7.2 メモリ使用量を減らす
7.2.1 オブジェクトのサイズを減らす
7.2.2 オブジェクトの初期化を遅らせる
7.2.3 immutableオブジェクトとcanonicalオブジェクト
7.2.4 Stringのintern化
7.3 オブジェクトのライフサイクル管理
7.3.1 オブジェクトの再利用
7.3.2 弱い参照、ソフト参照、その他の参照
7.4 まとめ
8章 ネイティブメモリのベストプラクティス
8.1 合計メモリ使用量
8.1.1 合計メモリ使用量の測定
8.1.2 合計メモリ使用量の最小化
8.1.3 NIOのネイティブなバイトバッファー
8.1.4 NMT
8.2 オペレーティングシステムのためのチューニング
8.2.1 large page
8.2.2 OOPの圧縮
8.3 まとめ
9章 スレッドと同期のパフォーマンス
9.1 スレッドプールとThreadPoolExecutor
9.1.1 スレッド数の最大値の設定
9.1.2 スレッド数の最小値の設定
9.1.3 タスクのキューのサイズ
9.1.4 ThreadPoolExecutorでのサイズ設定
9.2 ForkJoinPool
9.2.1 自動的な並列化
9.3 スレッドの同期
9.3.1 同期のコスト
9.3.2 同期の回避
9.3.3 false sharing
9.4 JVMのスレッドのチューニング
9.4.1 スレッドスタックのサイズ変更
9.4.2 バイアスロック
9.4.3 スレッドスピニング
9.4.4 スレッドの優先順位
9.5 スレッドとロックの監視
9.5.1 スレッドの可視化
9.5.2 ブロックされているスレッドの可視化
9.6 まとめ
10章 Java EEのパフォーマンス
10.1 基本的なWebコンテナのパフォーマンス
10.1.1 HTTPセッションの状態
10.2 スレッドプール
10.3 EJBのセッションBean
10.3.1 EJBのプールのチューニング
10.3.2 EJBキャッシュのチューニング
10.3.3 ローカルインスタンスとリモートインスタンス
10.4 XMLとJSONの処理
10.4.1 データのサイズ
10.4.2 マーシャリングとアンマーシャリング
10.4.3 パーサーの選択
10.4.4 XMLの検証
10.4.5 ドキュメントモデル
10.4.6 オブジェクトモデル
10.5 オブジェクトのシリアライズ
10.5.1 transientフィールド
10.5.2 デフォルトのシリアライズ処理の上書き
10.5.3 シリアライズされたデータの圧縮
10.5.4 重複したオブジェクトの管理
10.6 Java EEのネットワークAPI
10.6.1 送受信されるデータの削減
10.7 まとめ
11章 データベースのベストプラクティス
11.1 JDBC
11.1.1 JDBCドライバー
11.1.2 プリペアドステートメントとステートメントプール
11.1.3 JDBCのコネクションプール
11.1.4 トランザクション
11.1.5 リザルトセットの処理
11.2 JPA
11.2.1 トランザクションの処理
11.2.2 JPAでの出力の最適化
11.2.3 JPAでの入力の最適化
11.2.4 JPAのキャッシュ
11.2.5 JPAのキャッシュのサイズ設定
11.2.6 JPAの読み取り専用エンティティ
11.3 まとめ
12章 Java SEのAPIのパフォーマンス
12.1 バッファー付き入出力
12.2 クラスのロード
12.3 乱数の生成
12.4 JNI
12.5 例外処理
12.6 Stringのパフォーマンス
12.7 ログの記録
12.8 コレクションAPI
12.8.1 synchronizedか否か
12.8.2 コレクションのサイズ設定
12.8.3 コレクションとメモリの効率
12.9 AggressiveOpts
12.9.1 代替のクラス実装
12.9.2 その他のフラグへの影響
12.10 ラムダ式と匿名クラス
12.10.1 ラムダ式と匿名クラスのロード
12.11 Streamとフィルタリングのパフォーマンス
12.11.1 遅延アクセス
12.12 まとめ
付録A チューニングのフラグ
A.1 JITコンパイラ
A.2 ガベージコレクションのアルゴリズム
A.3 ガベージコレクションの全アルゴリズムに共通
A.4 スループット型ガベージコレクター
A.5 CMSガベージコレクター
A.6 G1ガベージコレクター
A.7 メモリ管理
A.8 スレッドの管理
A.9 その他のJVM関連のフラグ
A.10 Java Flight Recorder
索引
コラム目次
Oracleの商用JVM
クライアントクラスとサーバークラス
パフォーマンスは常に悪化する
バグやパフォーマンスはJVMだけの問題ではない
複数スレッドのマイクロベンチマーク
ウォームアップは行うべきか
複数のJVMを使った完全なシステムテスト
テストに利用したシステム
ウォームアップが必要とされるもう1つの理由
シンクタイムとスループット
ロードジェネレータ
統計とセマンティックス
統計的な重要さ
1プログラムあたりのCPU使用を制限する
情報過多?
JFRでのその他のイベント
レジスタとメインメモリ
コンパイラのフラグの違い
起動時間の重要性
32ビットか64ビットか
デフォルトのコンパイラを知るには
メモリの予約と割り当ての違い
OSRコンパイルの変更
jstatを使った検証
finalについて最後に一言
ガベージコレクションの強制的な実行と無効化
平均CPU使用率とガベージコレクション
メタスペースの肥大化
adaptive sizingとCMS
Java 8では非推奨になったiCMS
無条件の昇格、昇格の禁止
リージョンのサイズと大きなヒープ
浅いオブジェクトサイズと深いオブジェクトサイズ
ヒープダンプの自動取得
オブジェクトの配置とサイズ
初期化を遅らせることによるパフォーマンスへの影響
固定サイズのHashTable
Stringのintern()とequals()
ガベージコレクションの効率
用語の整理
ガベージコレクションのログと参照の処理
不定参照とコレクション
ファイナライザキュー
過剰な予約は問題か
NMTの詳細モード
同期とJavaの並列処理ユーティリティ
サンプルコードでのvolatile
競合とvolatile変数
Java 8と競合したアトミックなクラス
@Contendedアノテーション
ネイティブメモリの枯渇
UseSpinningフラグ
jstackのプロファイラ
EJBでのオブジェクトプールのコスト
EJBのオブジェクトプールの監視
サンプルデータのサイズ
パーサーファクトリーとパーサーの再利用
XMLのフィルタリングとJAX-WSライブラリ
Externalizableとは
ネットワーク通信の変容
サンプルデータベース
TRANSACTION_NONEと自動コミットモード
XAトランザクション
書き出すフィールドの数を減らす
フェッチグループ
JOINを使うための別の方法
リレーションの事前読み込み
テストのウォームアップ
synchronizedなコレクションのクラス
コレクション以外のクラスでの拡張
Java 7u40以降でのコレクションのメモリ使用量
続きを見る