ホーム

Topics

Javaにおけるガベージ・コレクション

Javaのガベージ・コレクションとは
JavaにおけるIBMのガーベッジ・コレクション・ソリューションの詳細はこちら AI関連の最新情報の購読を申し込む
ギア、ロボットアーム、携帯電話の絵文字のコラージュの図
Javaのガベージ・コレクションとは

ガベージ・コレクションは、エデン・スペースに作成されたオブジェクトのメモリーの割り当てと解放を自動的に管理するJavaプログラミング言語の重要な機能です。

Javaのガベージ・コレクションにより、開発者はメモリー管理を気にすることなくコードの記述に集中できるため、複雑で大規模なアプリケーションを構築するための選択肢としてJavaが人気を集めています。ただし、Java開発者がコードのパフォーマンスを最適化し、一般的なメモリー関連のエラーを回避するには、ガベージ・コレクションの仕組みを理解することが不可欠です。

このガイドでは、Javaのガベージ・コレクションの基礎について、そのメリット、さまざまな種類のコレクター、コーディング時のベスト・プラクティスなどについて説明します。それでは、ガベージ・コレクションがどのように機能するかを詳しく見ていきましょう。

IBM Robotic Process AutomationのTotal Economy Impact™

IBMロボティック・プロセス・オートメーション(RPA)のコストとメリットの分析をご覧ください。

関連コンテンツ オブサーバビリティーに関するガイドを読む
OutofMemoryErrorsとは

OutofMemoryErrorは、プログラムまたはアプリケーションが使用可能な量を超えるメモリーを割り当てようとしたときに発生するエラーの一種です。このエラーは、アプリケーションを実行しようとしたときに、Java仮想マシン(JVM)または別のプラットフォームのメモリーが不足した場合に発生します。

OutofMemoryErrorは通常、アプリケーションまたはプログラムが新しいオブジェクトを作成しようとしたが、JVMがそれらに対応するためにメモリーを割り当てることができない場合に発生します。このエラーは、アプリケーションがメモリーを過剰に使用し、適切に解放していない場合にも発生する可能性があります。

OutofMemoryErrorが発生すると、通常、アプリケーションはクラッシュして終了します。このエラーは、画像やビデオ処理アプリケーションなどの大量のメタデータを扱うプログラムや、大規模なデータベースを処理するプログラムでよく発生します。

このエラーを解決するには、アプリケーションで使用可能なメモリーの量を増やすか、アプリケーションのメモリー使用量を最適化する必要がある場合があります。これは、JVMパラメーターを変更するか、メモリー・プロファイラー・ツールを使用してメモリー・リークや非効率的なメモリー使用を特定することによって実行できます。

Javaにおけるガベージ・コレクションの仕組み

Javaでは、すべてのオブジェクトはヒープに格納されます。ヒープとは、オブジェクトの動的割り当て用に予約されているメモリーの一部です。オブジェクトがプログラムのどの部分からも参照されなくなると、そのオブジェクトはガベージ・コレクションの対象になります。

Javaのガベージ・コレクターは、ヒープ・メモリーを定期的にスキャンして、使用されていないオブジェクトを見つけます。ガベージ・コレクションのプロセスには、マーキング、スイープ、圧縮などのいくつかの手順が含まれます。

  • マーキング - ガーベッジ・コレクションの最初のステップでは、プログラムによって参照されているすべてのオブジェクトをマークします。これは、グローバル変数、ローカル変数、メソッド・パラメーターなどのルート・オブジェクトのセットから開始し、それらのルートから到達可能なすべてのオブジェクトをトレースすることによって実行されます。ルートからアクセスできないオブジェクトは、ガベージ・コレクションの対象とみなされます。

  • スイープ - マーキング段階が終了したら、ガベージ・コレクターはJavaヒープ全体をスイープし、参照されなくなったオブジェクトによって使用されているメモリーを識別して再利用します。これには、未使用のオブジェクトによって使用されているメモリーの割り当てを解除し、それを空きメモリー・プールに戻すことが含まれます。

  • 圧縮 - 一部のガベージ・コレクション・アルゴリズムでは、スイープ段階の後に圧縮段階が続き、残りのオブジェクトによって使用されるメモリーが再配置されて断片化が最小限に抑えられます。これには、オブジェクトを互いに近づけ、より大きな連続した空きメモリー・ブロックを作成することが含まれます。

Java仮想マシン(JVM)はガベージ・コレクションを自動的に実行するので、プログラマーが手動でメモリーを管理する必要がありません。ガベージ・コレクターは別のスレッドで実行され、通常はバックグラウンドで動作するため、プログラムの通常の実行には影響しません。

Javaにおけるガーベッジ・コレクターの種類

Javaのガベージ・コレクション・アルゴリズムには、完全なガベージ・コレクションと増分ガベージ・コレクションの2つの主な種類があります。・

完全な(または大規模な)ガベージ・コレクション

完全なガベージ・コレクションは、ガベージ・コレクター(プログラミング言語のランタイム・システムの一部)がプログラムによって使用されるすべてのメモリーを検索し、プログラムによって使用されなくなったオブジェクトをコンパイルするプロセスです。これらのオブジェクトはガベージとしてマークされ、メモリーから削除できるようになります。

完全なガベージ・コレクションは通常、JavaやPythonなどの自動メモリー管理を使用するプログラミング言語のランタイム・システムによって実行されます。プロセス中、ガベージ・コレクターはプログラムの実行を一時停止してガベージ・オブジェクトの検索を実行するため、プログラムのパフォーマンスが一時的に低下する可能性があります。

完全なガベージ・コレクションは通常、プログラムによって使用されるメモリーの量が特定のしきい値に達したとき、またはプログラムが新しいメモリー・ブロックを要求したが、使用可能な空きメモリーが十分にない場合にトリガーされます。完全なガベージ・コレクションの目的は、プログラムで必要のないメモリーを回収し、プログラムの他の部分や同じマシンで実行されている他のプログラムで使用できるようにすることです。

増分または軽微なガーベッジ・コレクション

増分ガベージ・コレクションは、プログラムで不要になったメモリーを自動的に再利用するためにプログラミング言語やランタイム環境で使用されるメモリー管理手法の一種です。これは、メモリー内で使用されていないオブジェクトを識別し、それらが占有しているメモリーを解放して、プログラムの他の部分で再利用できるようにすることで実現します。

増分ガベージ・コレクションでは、ガベージ・コレクターは定期的にプログラムのメモリーをスキャンし、若い世代のヒープ・メモリー内の到達不可能なオブジェクトを探します。ガベージ・コレクターは、このスキャン・プロセス中にプログラムの実行を停止するのではなく、スキャン・プロセスを「増分」と呼ばれる小さく管理しやすい部分に分割します。各増分中に、ガベージ・コレクターはプログラムのメモリーの一部をスキャンし、不要なオブジェクトを識別して、再利用可能であるとマークします。

増分を使用することで、ガベージ・コレクターは、プログラムの実行を長時間中断することなく、小さなチャンクでメモリーを再利用することができます。これにより、プログラムの応答性が維持され、ガベージ・コレクション・プロセスの結果として大幅な一時停止や遅延が発生しなくなります。

ただし、増分ガベージ・コレクションでは、プログラムのメモリーをより頻繁にスキャンする必要があるため、マーク・アンド・スイープや世代別ガベージ・コレクションなどの他の種類のガベージ・コレクション手法よりも効率が低くなる可能性があります。さらに、増分を使用すると、ガベージ・コレクターが各増分間の状態情報を維持する必要があるため、プログラムの実行にオーバーヘッドが発生する可能性があります。

Javaのガベージ・コレクションのメリット

全体として、Javaのガベージ・コレクションは多くのメリットを提供し、開発者にとって貴重なツールとなっています。Javaのガベージ・コレクションを使用するメリットは次のとおりです。

  1. 手動のメモリー管理不要
  2. メモリー・リークの防止
  3. メモリーの動的割り当て
  4. パフォーマンスの向上
  5. メモリーの最適化
  • 手動のメモリー管理不要:ガベージ・コレクションを使用すると、開発者はメモリーの割り当てと割り当て解除を手動で管理する必要がなくなります。つまり、プログラマーはメモリーの管理よりもコードの記述に集中できるため、エラーが減り、生産性が向上します。

  • メモリー・リークの防止:ガベージ・コレクションは、プログラムが不要になったメモリーを解放しない場合に発生する可能性があるメモリー・リークを防止するのに役立ちます。メモリー・リークが起きると、プログラムが必要以上にメモリーを消費し、パフォーマンスが低下し、最終的にはクラッシュする可能性があります。

  • メモリーの動的割り当て:Javaのガベージ・コレクションでは、メモリーの動的割り当てが可能になります。つまり、実行時に必要に応じてメモリーが割り当てられます。これにより、メモリーの割り当てエラーを防ぎ、プログラムの効率を高めることができます。

  • パフォーマンスの向上:ガベージ・コレクションは、メモリーの管理に費やす時間を削減することで、プログラムのパフォーマンスを向上させることができます。これにより、実行時間が短縮され、プログラムの応答性が向上します。

  • メモリーの最適化:ガベージ・コレクションは、プログラムの一部で使用されていないメモリーをプログラムの他の部分で再利用することで、メモリーの使用を最適化できます。これにより、メモリー使用量が削減され、プログラム全体の効率が向上します。

開発者は、Javaガベージ・コレクションのメモリーの自動管理、メモリー・リークの防止、メモリーの動的割り当て、パフォーマンスの向上、メモリー使用量の最適化などの機能の恩恵を受けることができ、ガベージ・コレクションは、開発者がより優れた効率的なプログラムを作成するのに役立ちます。

Javaのガベージ・コレクションをトリガーするイベントとは

Javaでは、ヒープがいっぱいになったと判断されたとき、または一定の時間が経過したときに、JVM(Java仮想マシン)によってガベージ・コレクションが自動的にトリガーされます。

Javaでガベージ・コレクションをトリガーできるイベントはいくつかあります。

  • ヒープ領域の割り当て:JVMが新しいオブジェクトにメモリーを割り当てる必要があり、ヒープに十分なスペースがない場合、未使用のメモリーを再利用するか、それらをSurvivor領域に格納するためにガベージ・コレクションがトリガーされます。

  • System.gc() メソッド呼び出し: System.gc() を呼び出すことで、ガベージ・コレクションを明示的に要求できます。ただし、実行される保証はありません。

  • 古い世代のしきい値:古い世代のヒープ領域(長期間存続するオブジェクトを格納する)のヒープ・サイズが特定のしきい値に達したときにも、ガベージ・コレクションがトリガーされることがあります。

  • PermGen/Metaspaceしきい値:Java8より前のバージョンのJavaでは、PermGen(Permanent Generation)またはMetaspace(Java8 以降)のメモリー領域のサイズが特定のしきい値に達したときにも、ガベージ・コレクションがトリガーされることがあります。

  • 時間ベース:場合によっては、時間間隔に基づいてガベージ・コレクションがトリガーされることがあります。例えば、JVMはメモリー使用量に関係なく、1時間ごとまたは1日ごとにガベージ・コレクションをトリガーする場合があります。

Javaでのガベージ・コレクションの正確な動作は、JVMの導入と構成によって異なる場合があることに注意してください。

JVMにガベージ・コレクターの実行を要求する方法

Java仮想マシン(JVM)にガベージ・コレクターの実行を要求するには、次の手順に従います。

  1. System.gc() メソッドを呼び出す:このメソッドは、JVMにガベージ・コレクターの実行を要求するために使用されます。このメソッドが呼び出された直後にガベージ・コレクターが実行されるかどうかは保証されません。

  2. Runtime.getRuntime().gc() メソッドを使用する:このメソッドはSystem.gc() メソッドに似ていますが、JVMの導入によってオーバーライドされる可能性は低くなります。
  3. -XX:+DisableExplicitGC JVMフラグを使用する:このフラグは、明示的なガベージ・コレクション要求を無効にします。つまり、System.gc() または Runtime.getRuntime().gc() を呼び出しても、ガベージ・コレクターはトリガーされません。

JVMはメモリー割り当てとガベージ・コレクションを自動的に管理するように設計されているため、ガベージ・コレクターの実行を明示的に要求することは通常は推奨されないことに注意してください。明示的なガベージ・コレクション要求は、パフォーマンスに悪影響を及ぼす場合があります。

オブジェクトがガベージ・コレクションの対象となるタイミング

プログラミング言語内のオブジェクトは、プログラムのどの部分からも参照されなくなったときに、ガベージ・コレクションの対象になります。自動ガベージ・コレクションは、プログラミング言語のランタイム環境によってメモリーを再利用するために実行されるプロセスです。

ほとんどの最新のプログラミング言語では、ガベージ・コレクションはランタイム環境によって自動的に実行されます。ガベージ・コレクションに使用される特定のアルゴリズムは、プログラミング言語と導入方法によって異なりますが、一般的な原則は同じです。ランタイム環境は、ヒープ(動的に割り当てられたオブジェクトに使用されるメモリーの部分)を定期的にスキャンして、プログラム内のライブ・オブジェクトからアクセスできなくなったオブジェクトを識別します。オブジェクトが到達不能であると識別されると、そのオブジェクトはガベージとしてマークされ、そのメモリーを再利用できるようになります。

オブジェクトがガベージ・コレクションの対象となる正確なタイミングは、ランタイム環境で使用される特定のガベージ・コレクション・アルゴリズムによって異なります。一部のアルゴリズムは他のアルゴリズムよりも積極的で、より迅速にメモリーを再利用する可能性がありますが、他のアルゴリズムはパフォーマンスを最適化するためにガベージ・コレクションを遅らせる可能性があります。ただし、一般的には、ランタイム環境が自動的にメモリーを管理するため、プログラマーが手動でメモリーを管理する必要はありません。

Javaで使用できるガベージ・コレクターとは

次のようなJavaガベージ・コレクターがあります。

  1. シリアル・ガベージ・コレクター
  2. パラレル・ガベージ・コレクター
  3. コンカレント・マーク・スイープ(CMS)コレクター
  4. G1ガベージ・コレクター
  • シリアル・ガベージ・コレクター: シリアル・コレクターはJavaのデフォルトのガベージ・コレクターであり、通常は高いスループットを必要としない小規模から中規模のアプリケーションで使用されます。このタイプのコレクターは、一般的な「世界停止」イベントの発生を防ぐのに役立ちます。

  • パラレル・ガベージ・コレクター:パラレル・コレクターは、高スループットのアプリケーション向けに設計されており、複数のCPUを使用してプロセスを高速化するため、大きなヒープを必要とするアプリケーションで特に役立ちます。このタイプのコレクターは、ガベージ・コレクターを実行するとアプリケーション・スレッドをフリーズすることに注意することが重要です。

  • コンカレント・マーク・スイープ(CMS)コレクター:CMSコレクターは、一時停止時間を短くする必要があるアプリケーション向けに設計されており、多数のライブ・オブジェクトを持つアプリケーションに役立ちます。

  • G1ガベージ・コレクター:G1コレクターは大きなヒープ用に設計されており、存続期間の短いオブジェクトと長いオブジェクトの混合を処理できます。複数のスレッドを使用してヒープのスキャンと圧縮を同時に行います。

各ガベージ・コレクターにはそれぞれ長所と短所があり、どのコレクターを使用するかはアプリケーションの特定のニーズに応じて選択されます。特定のアプリケーションのパフォーマンスを最適化するために、ガベージ・コレクターの設定を構成および調整することもできます。

ガベージ・コレクションとメモリー・リークの違い

ガベージ・コレクションとメモリー・リークはどちらもコンピューター・プログラムのメモリー管理に関連していますが、意味と影響は異なります。

前述のように、ガベージ・コレクションは通常、プログラミング言語またはランタイム環境によって実行され、プログラムが必要以上にメモリーを消費しないようにするのに役立ちます。ガベージ・コレクションは、プログラムの他の部分またはコンピューター上で実行されている他のプログラムが自由に使用できるメモリーを識別します。

一方、メモリー・リークは、プログラムが割り当てたメモリーが不要になった場合でも、そのメモリーを解放できない場合に発生します。その結果、プログラムは時間の経過とともにメモリーを消費し続け、最終的には使用可能なメモリーが枯渇し、プログラムまたはオペレーティング・システム全体がクラッシュする可能性があります。メモリー・リークは通常、プログラム内のバグによって発生し、特定して修正するのが難しい場合があります。

要約すると、ガベージ・コレクションは、不要になったメモリーを自動的に解放するプロセスです。メモリー・リークは、メモリーが割り当てられたがプログラムによって解放されない場合に発生し、メモリー使用量が徐々に蓄積されます。

InstanaはJavaアプリケーションのパフォーマンスを監視するのに役立ちます

結論として、ガベージ・コレクションは、未使用のメモリーを再利用することで効率的なメモリー管理を保証するJavaプログラミングの重要な側面です。Instanaのオブサーバビリティーは、ガベージ・コレクション・プロセスをリアルタイムで監視および最適化するための強力なツールを開発者に提供します。

Instanaを使用すると、開発者はメモリー・リークを迅速に特定し、ガベージ・コレクション設定を最適化し、ガベージ・コレクションに関連するパフォーマンスの問題をトラブルシューティングできます。

Instanaの包括的な監視機能により、開発者はJavaアプリケーションのメモリー使用量とガベージ・コレクションの動作に関する詳細な情報を得ることができ、高性能で信頼性の高いソフトウェアを提供できるようになります。

このガイドで概説されているベスト・プラクティスに従うことで、開発者はInstanaを使用してガベージ・コレクション・プロセスを最適化し、Javaアプリケーションの全体的なパフォーマンスを向上させることができます。Instanaのオブサーバビリティーにより、開発者は発生する可能性のあるあらゆる問題を事前に把握し、アプリケーションが常に最高のパフォーマンスを発揮できるようにすることができます。

関連製品
IBM Instana Observability

エンタープライズAPMの機能と可観測性を強化し、アプリケーションがどこにあってもアプリケーション・パフォーマンス管理を改善し、CI/CDパイプラインを高速化します。

IBM Instana Observabilityはこちら

参考情報 可観測性とは

可観測性により、最新の分散アプリケーションに対する詳細な可視性が提供され、問題の特定と解決がより迅速に自動化されます。

Java とは何ですか?

Java が依然として人気のある開発プラットフォームである理由と、Java がどのようにプロジェクトを加速し、幅広い新興テクノロジーをサポートするのかを学びましょう。

ソフトウェア開発とは何か。

ソフトウェア開発の基本と、それがどのようにビジネスの革新と競争に貢献するかを学びます。

Javaランタイム環境(JRE)とは

Javaランタイム環境(JRE)の機能と、他のJavaプラットフォーム・コンポーネントと連携してJavaアプリケーションを実行する方法について説明します。

アプリケーション・パフォーマンス管理(APM)とは

アプリケーション・パフォーマンス管理により、ビジネスに影響する前にパフォーマンスの問題を予測して防止できます。

サイト信頼性エンジニアリング(SRE)とは

サイト信頼性エンジニアリングにより、ITオペレーション・タスクを自動化し、ソフトウェア配信を加速し、ITリスクを最小限に抑えます。

次のステップ

IBM Instanaは、あらゆるユーザーの利用に適したリアルタイムの可観測性を提供します。可観測性戦略が現在および将来の環境の動的な複雑さに対応できることを検証しながら、価値実現までの時間を短縮します。 モバイルからメインフレームまで、Instanaは250以上のテクノロジーをサポートしており、その数は増え続けています。

IBM Instanaについて詳しく見る デモを予約