これは少し異なる例です。最終的な値型のローカル変数ではなく、最終的な参照型のフィールドがあります。
public class MyClass {
public final MyOtherObject obj;
}
MyClassのインスタンスを作成するたびに、MyOtherObjectインスタンスへの発信参照が作成され、GCはそのリンクをたどってライブオブジェクトを探す必要があります。
JVMはマークスイープGCアルゴリズムを使用します。これは、GCの「ルート」ロケーションにあるすべてのライブ参照を検査する必要があります(現在のコールスタック内のすべてのオブジェクトなど)。各ライブオブジェクトは生きているものとして「マーク」され、ライブオブジェクトによって参照されるオブジェクトも生きているものとしてマークされます。
マークフェーズの完了後、GCはヒープをスイープし、マークされていないすべてのオブジェクトのメモリを解放します(そして、残りのライブオブジェクトのメモリを圧縮します)。
また、Javaヒープメモリは「若い世代」と「古い世代」に分割されていることを認識することが重要です。すべてのオブジェクトは、最初は若い世代(「保育園」と呼ばれることもあります)に割り当てられます。ほとんどのオブジェクトは短命であるため、GCは若い世代から最近のゴミを解放することに積極的です。オブジェクトが若い世代の収集サイクルを生き延びた場合、そのオブジェクトは古い世代(「テニュア世代」と呼ばれることもあります)に移動され、処理の頻度は低くなります。
ですから、頭から離れて、「いいえ、「最終的な」モディファイアはGCの作業負荷を軽減するのに役立ちません」と言います。
私の意見では、Javaでメモリ管理を最適化するための最善の戦略は、偽の参照をできるだけ早く排除することです。使用が終わったらすぐにオブジェクト参照に「null」を割り当てることで、これを行うことができます。
または、さらに良いことに、各宣言スコープのサイズを最小化します。たとえば、1000行のメソッドの先頭でオブジェクトを宣言し、そのメソッドのスコープが閉じるまで(最後の閉じ中括弧)オブジェクトが存続する場合、オブジェクトは実際よりもはるかに長く存続する可能性があります。必要。
わずか12行程度のコードで小さなメソッドを使用する場合、そのメソッド内で宣言されたオブジェクトはより迅速にスコープから外れ、GCははるかに効率的な範囲内でほとんどの作業を実行できるようになります。若い世代。どうしても必要な場合を除いて、オブジェクトを古い世代に移動することは望ましくありません。