Javaでのガベージコレクション
Javaのガベージコレクションは、プログラムで使用されなくなったオブジェクトを削除することで、メモリを自動的に回収します。このプロセスは、メモリリークの防止、パフォーマンスの向上、そして開発者が手動でメモリを管理する手間の軽減に役立ちます。
ガベージコレクションは、コーディングの世界ではお馴染みの用語です。Javaプログラミング言語を学ぶ際にも、必ず目にするでしょう。Javaのメモリ管理機能に組み込まれているため、ガベージコレクターはJavaの重要な機能の一つです。ガベージコレクターは深刻なエラーを防ぎ、プログラマーが不要なオブジェクトを気にすることなく新しいオブジェクトを作成できるようにします。
しかし、ガベージコレクション(GC)を実行するバックグラウンドスレッドは予測不可能なタイミングで実行されるため、アプリケーションのパフォーマンスを低下させたり、速度を低下させたり、不要な遅延を引き起こしたりする可能性があります。このようなパフォーマンスへの影響から、開発者はプログラム実行時に遅延が発生しないように、適切なガベージコレクターを明確に理解する必要があります。
この記事では、Javaでのガベージコレクションに伴う詳細について説明します。 また、ガベージコレクションの主な利点と、ガベージコレクションがどのように機能するかについての簡単な説明が含まれており、開発者と管理者がアプリケーションでガベージコレクションをより簡単に使用できるようになります。
ガベージコレクションは、未使用のランタイムメモリを自動的に再利用するプロセスです。 つまり、未使用のオブジェクトは自動的に破棄されるため、開発者はメモリの割り当てや割り当て解除を気にせずに新しいオブジェクトを作成できます。
プログラマーがオブジェクトを手動で作成および破棄するCやC++などの言語では、冗長オブジェクトを管理して絶えず破棄するのは難しい場合があります。 保存されている不要なオブジェクトが多すぎると、システムのメモリが最新のオブジェクトを効率的に割り当てることができない場合があります。
さらに、手動で割り当てると、特にプログラマーが不要なメモリを解放しない場合や、実行中のコードでメモリヒープ内のオブジェクトにアクセスできない場合に、システムがメモリリークの影響を受けやすくなります。
Javaプログラムはで実行されます Java仮想マシン (JVM)バイトコードの形式。 JVMは、バイトコードを解釈してプログラムを実行し、ヒープスペースまたはプログラムに割り当てられたメモリ部分にオブジェクトを作成できるようにします。
新しいオブジェクトの作成と解放は、一部のオブジェクトが完全に不要になるまで続きます。 その時点で、ヒープにはXNUMXつのタイプのオブジェクトが含まれています。これらは次のように記述できます。
デッド:不要なオブジェクトまたは使用されなくなったオブジェクト。
ライブ: 使用中および参照中のオブジェクト。
Java のガベージ コレクションはメモリを自動的に管理するため、開発者は効率的で高性能なアプリケーションの構築に集中できます。
多くのプログラマーは、明示的なストレージ再利用のパフォーマンスは、メモリ管理における自動ガベージコレクションよりも優れていると考えています。 ただし、いくつか 研究 ガベージコレクターの下で十分に開発されたシステムは、明示的な割り当て解除を使用したシステムよりも優れた結果を生み出すことを示しました。 ガベージコレクションの利点のいくつかを次に示します。
Javaのガベージコレクションは、価値のあるオブジェクトと価値のないオブジェクトを識別し、未使用のオブジェクトを排除することによってヒープメモリを実行する自動操作です。 プログラムの実行中のコードが到達できないオブジェクトは、解放して使用できるメモリを占有します。
他の言語とは異なり、JVMはJavaで不要なデータを管理するため、プログラマーはオブジェクトによって実行されるすべてのアクティビティを制御する必要はありません。 JVMはガベージコレクターを指示します。 したがって、ヒープが大きくなるたびに、JVMはクリーンアッププロセスを自動的に実行します。
次に、XNUMXつの基本的な手順でガベージコレクションがどのように行われるかを確認します。
マーク、スイープ、およびコンパクトアルゴリズムは、最も基本的なガベージコレクションレベルです。 ただし、ほとんどのオブジェクトは短命であるため、フルマーク、スイープ、およびコンパクトプロセスの実行に失敗する可能性があります。
その結果、プログラマーは、すべての短期間のオブジェクトを確実に管理するために、より効率的なGCアルゴリズムを必要としています。
世代別ガベージコレクションアルゴリズムは、ガベージをより効率的に収集するために、オブジェクトの寿命の観点からオブジェクトを配置します。 ガベージコレクターは、その存在期間に応じて異なるレベルを作成することにより、すべての短命のオブジェクトで完全に動作することを保証します。 さらに、ヒープメモリを若い世代と古い世代のXNUMXつの主要なコンパートメントに分割します。
若い世代はすべての新しいオブジェクトを運びます。 これは、EdenとSurvivorのXNUMXつのパーティションに分割されています。
エデン:すべての新しいオブジェクトは、ガベージコレクションサイクルごとに、サバイバーパーティションに移動する前にここに配置されます。
サバイバー:サバイバーはSOとS1に分けられ、FromSpaceとToSpaceとも呼ばれます。
オブジェクト割り当てのフローは次のようになります。
旧世代に昇格する前に、ガベージコレクションはXNUMX番目とXNUMX番目のステップで時間がかかります。 オブジェクトが長寿命であると識別された後、ガベージコレクタはそれらを古いオブジェクトに移動します。
若い世代とは異なり、このコンパートメントにはマーキングとスイープが含まれ、主要なGC操作が実行されます。 完全なガベージコレクションは、古い世代と若い世代の両方をクリーンアップします。 これは、若い世代から古い世代まですべての生きているオブジェクトを宣伝し、スペースを圧縮することによって発生します。
古い世代は、既存のすべてのオブジェクトを保護し、完全なガベージコレクションが開始されたときにアプリケーションを一時停止することで、新しいオブジェクトがヒープメモリに移動されないようにします。
ガベージコレクションには、次のXNUMX種類のアクティビティが含まれます。
この操作は若い世代で実行され、ヒープメモリで見つかった到達不能なオブジェクトをクリアします。
メジャーガベージコレクションは、マイナーガベージコレクションによってクリアされず、古いヒープメモリにコピーされたオブジェクトを検索して削除するために実行されます。 生き残ったオブジェクトは、新しいオブジェクトを順番に配置するために圧縮されます。 このフェーズでは、ガベージコレクションの頻度は若い世代よりも少なくなります。 また、このパーティションでのガベージコレクションの頻度は低くなります。
参照されていないオブジェクトは、プログラマーにとって価値がなくなったオブジェクトを示します。 この場合、すべてのオブジェクトから基準点を引いたものは不要と見なされます。 ヒープメモリにスペースを作成するために、ガベージコレクタはこれらの参照されていないオブジェクトを破棄し、メモリを再利用して圧縮し、新しい割り当てのためにスペースを準備します。
プログラマーは不要なオブジェクトを破棄する責任はありませんが、不要になったオブジェクトを到達不能にする必要があります。 参照されていないオブジェクトが削除されない場合、それらはヒープメモリをいっぱいにし、プログラムのパフォーマンスを妨害します。 これらは通常、メモリリークと呼ばれます。 オブジェクトへの参照を省略してガベージコレクションの対象にすることができる簡単なトリックがあります。 それらが含まれます:
ガベージコレクションのルートは、ガベージコレクションプロセスにおける一意のオブジェクトです。 これらは主にガベージコレクションの開始点であり、JVMによって参照されます。 したがって、直接または間接的に参照される他のすべてのオブジェクトがガベージコレクションされないようにします。 すべてのアプリケーションまたはプログラムは、ツリーの他の部分に到達するためにルートにアクセスできる必要があります。 以下は、JavaのXNUMXつの主要なガベージコレクションルートです。
ガベージコレクションは、参照されていないオブジェクトをヒープから削除し、新しく設計されたオブジェクトに十分なスペースを提供することにより、Javaメモリで重要な役割を果たします。 JVMは異なります ガベージコレクターの種類。 それぞれの包括的な詳細は次のとおりです。
シリアルガベージコレクターは、シングルスレッドプロセスで実行されるアプリケーション用に明示的に開発されました。 シリアルGCは、すべてのマルチスレッドアプリケーションをブロックして、アクティビティを実行するときにXNUMXつのスレッドでシリアルに収集を実行します。 ガベージコレクションサイクルごとに、シリアルガベージコレクターはメモリを圧縮して、メモリの断片化を回避します。
一時停止時間が短いアプリケーションは、ガベージコレクションに干渉する可能性があるため、お勧めしません。 この干渉は通常、シリアルGCが一時停止アプリケーションを開始している間にアプリケーションが通常のアクティビティを再開したときに発生します。これは一般に「ワールドイベントの停止」として知られています。
並列GCは、マルチスレッドプロセッサを介してヒープメモリシステムを実行し、通常はJVMでのアクティビティのデフォルトのアプリケーションであるため、大規模なデータで効率的に機能します。 若い世代のマイナーガベージコレクションは複数のスレッドを使用しますが、古い世代のメジャーガベージコレクションは単一のスレッドを使用します。
シリアルGCと同様に、パラレルガベージコレクターにも「stopthe worldイベント」があり、現在ガベージコレクションを処理しているアプリケーションを一時停止します。 このタイプのコレクターは、長い休止が必要になる可能性のある多くの作業を行う場合に適しています。
これは、Java7u4以降の古いバージョンの並列GCです。 並列GCとは少し異なります。これは、若い世代と古い世代のマルチスレッドプロセッサを実行するためです。 このコレクターを使用すると、プログラマーはガベージコレクタースレッドの数を制御し、最大休止時間の目標を指定し、最大スループットの目標を指定できます。
CMSガベージコレクターは、コンカレントローポーズコレクターとも呼ばれ、ガベージコレクションをノンストップで処理する機能を意味します。
さらに、マイナーガベージコレクションでのアクティビティは、複数のスレッドプロセスで実行されます。 マルチスレッドプロセスは、より多くのCPUスペースを使用するため、他のガベージコレクターよりもアプリケーションでうまく機能します。 また、CPUスペースが多いほどパフォーマンスが向上する場合は、並列コレクターよりもCMSガベージコレクターの方が適しています。 ただし、状況によっては、アプリケーションのパフォーマンスが低下する場合があります。
G1ガベージコレクターは、並列および同時パフォーマンスの点でCMSガベージコレクターと同様に機能します。 ただし、これは主にCMSガベージコレクターJDK1.7を置き換え、GCの分野でより良いエクスペリエンスをもたらすために作成されました。 G1は、マークスイープアルゴリズムを使用してガベージコレクションを実行します。 パフォーマンス効率が高いため、G1は最終的にCMSに取って代わる可能性があります。
メモリヒープを同じサイズの領域のセットに分割し、複数のスレッドを使用してそれらをスキャンします。
その名前「ガベージファースト」は、G1のガベージコレクションアクティビティに由来しています。これには、最初に空の領域を特定して、メモリシステムにより多くの空き領域を生成することが含まれます。
EpsilonはJDK11のアップデートであり、パッシブまたは非動作のガベージコレクタとしてリリースされました。 メモリ割り当てを実行するだけですが、Javaヒープメモリが使い果たされた後にJVMがシャットダウンするため、メモリ割り当てを取得できません。 さらに、Epsilonガベージコレクターは、メモリが不足してクラッシュするアプリケーションで効率的に動作できます。
ガベージコレクターによって引き起こされる非効率性を測定、制御、および排除することにより、アプリケーションのパフォーマンスを向上させることを目指しています。 また、ガベージコレクターがアプリケーションのスムーズな実行とメモリのしきい値にどのように影響するかを理解するために、ガベージコレクターがなくなるたびに表示します。 アプリケーションのパフォーマンスを最適化したいユーザーにとって、Epsilonガベージコレクターは実行可能な選択肢です。
ShenandoahはJDK12の一部としてリリースされました。これにより、Javaプログラムがバックグラウンドで操作を続行できるようにしながら、一時停止時間を短縮することで、ガベージコレクターのエクスペリエンスが向上しました。 さらに、Shenandoahは、超低休止時間GCを使用して、すべてのライブオブジェクトを正常にマークし、メモリスペースの同時圧縮を生成します。
G1とは異なり、Shenandoahのガベージコレクションサイクルはアプリと同時に実行されます。 ライブオブジェクトを圧縮して再配置するためにアプリケーションを一時停止する必要はありません。 これにより、CPUがより集中的になります。
Shenandoahは、すべてのヒープオブジェクトに転送ポインターを追加することでオブジェクトへのアクセスも制御し、パーティション化された領域内でオブジェクトを簡単に移動できるようにします。 また、アプリケーションスレッドと並行してヒープを積極的に圧縮する機能により、他のガベージコレクターとは一線を画しています。
ZGCは、低遅延が必要なアプリケーションや、巨大なヒープ(数テラバイト)を使用するアプリケーションに最適です。 色付きのポインターを使用して、スレッドの実行中に操作を実行することにより、ヒープの使用状況を追跡します。 ZGCは使いやすく、拡張性に優れています。 ガベージコレクションアクティビティを実行するときにJavaアプリケーションを実行できます。
その短い休止時間は、他のガベージコレクターに比べて大幅な改善をもたらします。 このコレクターによるパーティションはサイズが異なります。 ZGCは、次のXNUMXつのフェーズでマーキングを行います。
Javaメモリ管理は、オブジェクトの割り当てと割り当て解除のプロセスです。 これは、プログラマーの直接の介入を必要としない自動プロセスです。
ただし、自動プロセスがすべてを保証するわけではありません。 つまり、プログラマーは、クラッシュしない高性能ベースのプログラムを作成するために、Javaのメモリ管理がどのように機能するかを知る必要があります。 それらがクラッシュした場合でも、プログラマーはデバッグ方法を知っています。 メモリを管理することで、パフォーマンスに影響を与える可能性のあるリークを防ぎます。
Javaメモリ管理の中心的な概念は、JVMメモリ構造とガベージコレクタの動作です。
ガベージコレクターの動作について包括的に説明したので、JVMのメモリ構造を見てみましょう。
JVMは、プログラムの実行中に使用されるさまざまな実行時データ領域を定義します。 一部の領域はJVMによって作成され、他の領域はプログラムで使用されるスレッドによって作成されます。 JVMによって作成されたメモリ領域は、JVMが終了すると破棄されます。 スレッドによって作成されたデータ領域にも同じことが当てはまります。
Javaメモリ領域は、ヒープ、メソッド領域、JVMスタックネイティブメソッドスタック、PCレジスタなどのさまざまな部分で構成されています。
各領域は特定のタスクを実行し、最終的な目標はプログラムを正常に実行することです。
Javaでのガベージコレクションは自動プロセスですが、スキルを向上させたいプログラマーは、ガベージコレクションがどのように機能するかを学ぶ必要があります。 これは、Javaヒープメモリが適切に構成および管理されていることを確認することにより、ガベージコレクションアクティビティを最適化するのに役立ちます。
また、最適なJavaアプリケーションのパフォーマンスを得るには、ガベージコレクションを監視することが不可欠です。 これにより、ユーザーは中断やダウンタイムなしでプログラムを簡単に実行できます。
© LogicMonitor 2025 | 無断複写・転載を禁じます。 | ここで言及されているすべての商標、商号、サービス マーク、およびロゴは、それぞれの会社に帰属します。