Closed4
読書メモ: Optimizing Java

書籍
配布ソース

Chapter 1. Optimization and Performance Defined
- JVM アプリケーションの観測されたパフォーマンス測定値は正規分布していない
- 基本的な統計手法は JVM アプリの結果の処理に適していない
- パフォーマンスは実験科学
- 望ましい結果の定義
- 既存システムの測定
- 案件を達成するために何をすべきかを決定する
- 改善演習の実施
- 再テスト
- 目標が達成されたかどうかの判断
- Throughput
- 通常ある期間の作業単位数として表される
- スループットテストのワークロードが実行間で一定に保たれるようにする必要がある
- Latency
- 配管の比喩でいうと、パイプの長さがレイテンシー
- エンドツーエンド時間として引用される
- ワークロードに依存
- Capacity
- システムが持つ作業の並行処理の量
- システム内で同時に進行できる作業単位(トランザクションなど)の数
- スループットやレイテンシーに関係
- 特定のスループットやレイテンシーに対する利用可能な値として引用される
- Utilization(リソースの使用率)
- システムのリソースを効率的に使用している場合、アイドル状態は減る
- 計算集約型のワークロードは、CPU 100% でもメモリ使用率は低い場合がある
- Efficiency
- スループットを使用されたリソースで割ると、システムの全体的な効率の尺度が得られる
- 同じスループットを出すためにより多くのリソースを必要とするのは非効率
- スループットをコストで割ることで効率を見る手法もある
- Scalability
- リソースが追加された時のスループットの変化は、スケーラビリティの尺度の一つ
- スケーラビリティの究極の目標はスループットをリソースに合わせて正確に変化させること
- 完全に線形スケーリングを達成することは困難
- Degradation(劣化)
- システムの負荷を増やした場合に観測されたレイテンシーやスループットに変化が見られる場合がある
- 負荷を増やす: リクエスト(またはクライアント)の数を増やす、リクエストが到着する速度を上げるなど
- 使用率に依存する
- リソースが完全に使用されている場合は、スループットの増加は停止するかレイテンシーが増加
- 追加負荷下でのシステムの劣化(the degradation of the system under additional load)と呼ばれる
- リソースが完全に使用されている場合は、スループットの増加は停止するかレイテンシーが増加
- システムの負荷を増やした場合に観測されたレイテンシーやスループットに変化が見られる場合がある
- Connections Between the Observables
- パフォーマンスオブザーバブルの動作は、通常何らかの方法で接続している
- システムがピークユーティリティ(peak utility)で実行されているかどうかで異なる
- システムが活用されていない場合、負荷を増やしても使用率がそれほど向上しない可能性もある
- スケーラビリティと劣化は、どちらも負荷が追加されたときのシステムの動作を表す
- 負荷が上がってもレイテンシが短縮することもある
- 追加の負荷によって一部のリソースが集中的に使用されることでパフォーマンスが高いモードに切り替わる場合など
- 例: HotSpot の JIT コンパイラー
- 追加の負荷によって一部のリソースが集中的に使用されることでパフォーマンスが高いモードに切り替わる場合など
パフォーマンス グラフの読み取り
- パフォーマンスエルボー
- 負荷が増加した状態での突然の予期しないパフォーマンスの低下
- 線形にスケーリングするのが好ましい
- 単一サーバーとのセッションアフィニティを必要としないステートレスプロトコルのスケーリングなど、有利な状況でのみ達成される可能性がある
- アムダールの法則
- タスクに割り当てられたプロセッサーの数の関数として可能な最大のスピードアップを示す
- ワークロードにシリアル実行する必要がある場合は、線形のスケーラビリティの達成は不可能
- メモリ使用量
- GC により正常なアプリケーションで使用されるメモリはノコギリ(sawtooth)パターンを発生させる
- メモリグラフによりメモリ割り当てに問題があるか、などを読み取れる
- リソースリーク
- リークがある場合、システムが急速に劣化する変曲点到達前に負荷が増加するにつれて観測可能な値(レイテンシーなど)がゆっくりと劣化

Chapter 2. Overview of the JVM
- JVM はスタックベースのインタープリターマシーン
- レジスタを持つのではなく、部分的な実行スタックを使用
- スタックの最上位の値を(または複数の値)を操作して計算を実行
-
javac
によって class ファイルに変換される際には最適化はほとんどされない
Introducing HotSpot
- 言語ごとの方向性
- ゼロコストの抽象化などのアイデアを志向
- C++ や Rust など
- 低レベルの現実に対処する必要がある
- パフォーマンスを気にしない開発者には重大な認知負荷となる
- AOT コンパイルが必要
- 低レベルの制御をする必要がない生産性を志向
- Java はゼロオーバーヘッドは志向していない
- HotSpot 仮想マシンはプログラムの実行時の動作を分析 & 最適化を実行
- Java はゼロオーバーヘッドは志向していない
- ゼロコストの抽象化などのアイデアを志向
- JIT
- 最大のパフォーマンスを得るにはネイティブ実行が必要
- HotSpot はプログラムのユニットをクラスのバイトコードからネイティブコードにコンパイルすることで実現
- コンパイルの単位: メソッドとループ
- 最も頻繁に実行されるコードの部分を観察して機能する
- 特定のメソッドの実行が閾値を超えると Profiler はコードの特定のセクションをコンパイル及び最適化
- トレース情報など多くの情報に基づいた最適化が行える
JVM Memory Management
- メモリ管理は難しい
- Java は GC を使用して自動的に管理されるヒープメモリを導入
- GC にはコストがかかる
- Stop The World が発生
- GC は Java パフォーマンスの最適化の主要トピック
- 後述
- GC にはコストがかかる
スレッド化と Java メモリモデル
- マルチスレッドプログラミングの組み込み
- Java の最初のバージョンでもたらした大きな進歩
- マルチスレッドにより動作がより複雑になり、パフォーマンス解析作業が困難になる
- Java のスレッドは OS のスレッドに対応
- グリーンスレッドは許容できるパフォーマンスプロファイルを提供出来なかった
- Java のマルチスレッドへのアプローチの基本設計
- Java プロセス内のすべてのスレッドは 1 つの共通の GC ヒープを共有
- あるスレッドによって作成されたオブジェクトは、そのオブジェクトへの参照を持つ他のスレッドからアクセスできる
- オブジェクトはデフォルトで変更可能
- 明示的に final を指定しない限り変更できる
- Java Memory Model(JMM)
- さまざまな実行スレッドがオブジェクトの値をどのように認識するのかを説明するモデル
- OS のスケジューラは CPU コアからスレッドを強制的に追い出すことができる
- Java のコアの防御策については後述
JVM について
- Oracle の実装である HotSpot から派生した JVM はいくつかある
- OpenJDK
- Java のリファレンス実装を提供する OSS プロジェクト
- Oracle によって主導およびサポート
- Java リリースの基礎となる
- Oracle
- OpenJDK に基づいている
- Oracle のプロプライエタリライセンス下で再ライセンス
- Oracle Java に対するほとんどすべての変更は OpenJDK にも反映
- zulu
- GPL ライセンスの OpenJDK 実装
- Azul Systems によって提供
- Azul OpenJDK の有料サポートを提供するベンダー
- IcedTea
- Red Hat によって提供
- OpenJDK 認定 & 再配布可能
- zing
- 高性能の専用 JVM
- Java 認定実装
- 64 ビット Linux 専用で大きなヒープ(数十から数百 GB)と大量の CPU を備えたサーバーシステム向けに設計
- Azul Systems によって提供
- J9
- IBM のプロプライエタリな JVMとして誕生 & OSS 化された
- Eclipse Open Runtime Project の上に構築
- Avian
- 教育用の実装
- 100% 準拠しているわけではない
- JVM の仕組みの詳細を理解するための学習ツール
- Android
- non-JVM virtual machine
- cleanroom Harmony project の Java クラスライブラリと
.dex
フォーマットへのクラスコンパイラーを組み合わせている
- この本は HotSpot に焦点を当てる
- OpenJDK 派生の JVM に等しく適用できる

https://zenn.dev/link/comments/303f5fe2052859 でまとめていくので、close
このスクラップは2023/10/13にクローズされました