Javaのガベージ・コレクションとは

成層圏雲の中の上海陸家嘴の空撮

Javaのガベージ・コレクションとは

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

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

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

The DX Leaders

AI活用のグローバル・トレンドや日本の市場動向を踏まえたDX、生成AIの最新情報を毎月お届けします。登録の際はIBMプライバシー・ステートメントをご覧ください。

ご登録いただきありがとうございます。

ニュースレターは日本語で配信されます。すべてのニュースレターに登録解除リンクがあります。サブスクリプションの管理や解除はこちらから。詳しくはIBMプライバシー・ステートメントをご覧ください。

OutofMemoryErrorsとは

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

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

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

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

アプリケーション開発

さあ、クラウドでエンタープライズ・アプリケーション開発を始めましょう

この動画では、Peter Haumer博士が、IBM Z Open Editor、IBM Wazi、Zoweなどのさまざまなコンポーネントとプラクティスを実演しながら、ハイブリッドクラウドでの最新エンタープライズ・アプリケーション開発について説明します。

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のエンタープライズ向けJavaアプリケーション・サービス

Javaアプリケーションを開発および配信するためのフルマネージドのシングルテナント・サービス。

Javaアプリの詳細はこちら
DevOpsソリューション

DevOpsソフトウェアとツールを使用して、複数のデバイスや環境でクラウドネイティブ・アプリケーションを構築、デプロイ、管理します。

DevOpsソリューションの詳細はこちら
エンタープライズ・アプリケーション開発サービス

クラウド・アプリケーション開発は、一度構築すれば、迅速に反復し、どこにでもデプロイできます。

アプリケーション開発サービス
次のステップ

IBM Cloudアプリケーション開発コンサルティング・サービスは、クラウド戦略を合理化するための専門家のガイダンスと革新的なソリューションを提供します。IBMのクラウドおよび開発のエキスパートと提携して、アプリケーションをモダナイズ、拡張、高速化し、ビジネスに変革をもたらします。

アプリケーション開発サービスの詳細はこちら IBM Cloudを無料で構築開始