概要
JavaのパフォーマンスチューニングポイントのNoteです。
チューニングポイント
(1) 可能な場合は、オブジェクト型ではなくプリミティブ型を使用して、メモリ使用量を削減します。
- プリミティブ型は、ヒープではなくスタックに直接格納されるため、オブジェクト型よりもメモリ使用量が少なくなります。
- スタック
- スタックという文字の通り、実行される場合はこの領域に、格納され、終わるとここから取り除かれる。1スレッドで1つの領域が使われる。
- 値型はここに格納される。
- 特定のスコープのみに対して使用されるため、メモリ管理がしやすい反面、大きいデータの格納には向いていない。
- オブジェクトのデータはポインタがここに格納され、実データは後述するヒープ領域で管理される。
- ヒープ
- 開始時に一定領域確保され、必要の都度アプリケーションに割り当てられる。
- 大きいデータ、スコープがはっきりしないもの、サイズが動的なデータなどの格納に向いている。
- 領域が動的な代わりに少し遅い。
- クラスの実態はこの領域に実データが格納される。
- スタック

(2) String 連結の代わりに StringBuilder または StringBuffer を使用して、新しい String オブジェクトが作成されないようにします。
- 文字列連結は連結ごとに新しい String オブジェクトを作成しますが、StringBuilder と StringBuffer は同じオブジェクトをその場で変更するため、不要なオブジェクトの作成が回避されます。
(3) 可能な場合はオブジェクトを再利用して、不要なオブジェクトの作成を回避します。
- オブジェクトの作成には、メモリの割り当てとオブジェクトの初期化が含まれるため、コストが高くなる可能性があります。オブジェクトを再利用すると、メモリ使用量が削減され、パフォーマンスが向上します。新しいオブジェクトを作成する代わりに、オブジェクトのプールを使用します。
(4) ジョブに適切なデータ構造を使用して、メモリ使用量を最小限に抑えます。
- データ構造が異なれば、メモリ使用量の特性も異なります。適切なデータ構造を使用すると、メモリ使用量が削減され、パフォーマンスが向上します。
(5) 遅延初期化を使用して、実際に必要になるまでオブジェクトを作成しないようにします。
- オブジェクトを不必要に作成すると、メモリが浪費され、パフォーマンスが低下する可能性があります。遅延初期化により、オブジェクトが実際に必要なときにのみ作成されます。ユーザーから要求された場合にのみオブジェクトを初期化する
(6) try-with-resources を使用して、ストリームやその他のリソースが不要になったときに適切に閉じられるようにします。これにより、メモリリークが防止されます。
- ファイル入力ストリームなどのリソースは、メモリリークを回避するために適切に閉じる必要があります。try-with-resources は、例外がスローされた場合でもリソースが閉じられるようにします。
(7) 変数のスコープを最小化して、メモリ使用量を削減します。たとえば、変数を可能な限り最小のスコープで宣言して、必要な期間だけメモリに保持されるようにします。
(8) 不必要なメモリ使用を防ぐために、静的変数の使用は避けてください。
(9) メモリ使用量を減らすために、スレッドが多すぎないようにします。
- スレッドの作成には、メモリ割り当てとコンテキストの切り替えが含まれるため、コストが高くなる可能性があります。スレッド プールを使用すると、メモリ使用量が削減され、パフォーマンスが向上します。
(10) キャッシュを使用して、メモリ使用量を減らし、パフォーマンスを向上させます。- キャッシュにより、操作の実行回数が減り、メモリ使用量が減り、パフォーマンスが向上します。
(11) メモリ プロファイラーを使用して、メモリ リークやその他のメモリ関連の問題を特定します。サンプルツール、VisualVM、JProfilerなど
Note
新しいJavaバージョンでの変更は、これらのポイントが最新のメモリ改善とどの程度一致するかに影響を与える可能性がありますが、理解して使用することは重要です。