メモリ内のオブジェクトに参照がない場合、オブジェクトが使用されなくなり、ガベージコレクションの候補になる可能性があります。ただし、ゴミコレクターの実行時間は不確かであるため、収集できるオブジェクトの実際のリサイクル時間は不確かです。オブジェクトの場合、参照がある限り、それは常にメモリに存在します。このようなオブジェクトがますます多く、JVMのメモリ全体を超えると、JVMはOutFmemoryエラーをスローします。ガベージコレクションの特定の操作はJVMによって制御されていますが、開発者はガベージコレクターとある程度相互作用することができ、目的はガベージコレクターがアプリケーションのメモリを管理するのをよりよく支援することです。この相互作用方法は、JDK 1.2によって導入されたjava.lang.refパッケージを使用することです。
1強い引用
強力な引用は、使用される最も一般的な引用です。オブジェクトに強い参照がある場合、ゴミコレクターはそれをリサイクルしません。メモリスペースが不十分な場合、Java仮想マシンは、プログラムを異常に終了させるためにOutMemoryErrorエラーを投げかけ、強い参照でオブジェクトをリサイクルして、メモリ不足の問題を解決することはありません。
たとえば、日付date = new date()、日付はオブジェクトへの強力な参照です。オブジェクトへの強い参照は、プログラムのどこでも渡すことができます。多くの場合、複数の参照が同じオブジェクトを同時に指します。強い参照の存在は、メモリ内のオブジェクトの生存時間を制限します。オブジェクトAにオブジェクトBへの強い参照が含まれている場合、一般に、オブジェクトBの生存時間はオブジェクトAより短くなりません。オブジェクトAがオブジェクトBの参照をnullに明示的に設定しない場合、オブジェクトAが収集されたゴミA後にのみ、オブジェクトBはそれを指す参照を持ち、ガベージ収集の機会を得ることができます。
例コード:
パッケージcom.skywang.java; public class strongreferencetest {public static void main(string [] args){mydate date = new mydate(); System.gc(); }}実行結果:
<出力なし>
結果は、ガベージコレクションが明示的に呼ばれているにもかかわらず、日付の強力な参照であり、日付がリサイクルされないことを示しています。
強力な参照に加えて、java.lang.refパッケージは、オブジェクトに異なる参照方法を提供します。 JVMのゴミコレクターには、さまざまな種類の参照を処理するさまざまな方法があります。
2つのソフトクォート
オブジェクトにソフト参照のみがある場合、メモリスペースで十分であり、ガベージコレクターはそれをリサイクルしません。メモリスペースが不十分な場合、これらのオブジェクトのメモリがリサイクルされます。ゴミコレクターがリサイクルしない限り、オブジェクトはプログラムで使用できます。ソフト参照を使用して、メモリに敏感なキャッシュを実装できます。
ソフトリファレンスは、参照キュー(リファレンスキュー)と組み合わせて使用できます。ソフト参照によって参照されるオブジェクトがガベージコレクターによってリサイクルされている場合、Java仮想マシンは、関連する参照キューにソフト参照を追加します。
ソフト参照は、強度の強い参照よりも弱く、ソフトレフェンスによって表されます。その機能は、プログラム内のオブジェクトがそれほど重要ではなく、メモリが不十分な場合に一時的にリサイクルできるかどうかをガベージコレクターに伝えることです。 JVMにメモリが不十分な場合、ゴミコレクターはソフト参照によってのみ指摘されるオブジェクトを自由にします。これらすべてのオブジェクトがリリースされ、メモリが不十分な場合、OutFmemoryエラーがスローされます。ソフト参照は、キャッシュを作成するのに理想的です。システムが不十分な場合、キャッシュ内の内容をリリースできます。たとえば、画像エディタープログラムを検討してください。プログラムは、画像ファイルのすべてのコンテンツをメモリに読み取り、簡単に処理します。ユーザーは、複数のファイルを同時に開くこともできます。ファイルが多すぎると同時に開かれている場合、メモリが不十分な場合があります。ソフト参照が画像ファイルの内容を指すために使用される場合、Garbage Collectorは必要に応じてこのメモリを取り戻すことができます。
例コード:
パッケージcom.skywang.java; import java.lang.ref.softreference; public class softreferencetest {public static void main(string [] args){softreference ref = new MyDate(); Referencetest.drainmemory(); }}実行結果:
<出力なし>
結果:メモリが不十分な場合、ソフト参照が終了します。ソフト参照が禁止されている場合、
softreference ref = new softreference(new mydate()); referencetest.drainmemory();
に相当
mydate date = new mydate(); // jvm次第ですif(jvm.insuftiveer memory()){date = null; system.gc();} 3つの弱い引用
弱い参照は、強度のソフト参照よりも弱く、弱者クラスで表されます。その目的はオブジェクトを参照することですが、オブジェクトがリサイクルされるのを妨げません。参照が存在する限り、強力な参照が使用される場合、参照されるオブジェクトをリサイクルできません。弱い引用にはこの問題はありません。ゴミコレクターが実行されている場合、オブジェクトへのすべての参照が弱い参照である場合、オブジェクトはリサイクルされます。弱い参照の機能は、強力な参照によってもたらされる生存時間のオブジェクト間の結合関係を解決することです。弱い参照の最も一般的な使用は、特にハッシュテーブルのコレクションクラスです。ハッシュテーブルインターフェイスにより、任意のJavaオブジェクトをキーとして使用できます。キー価値ペアがハッシュテーブルに入れられると、ハッシュテーブルオブジェクト自体には、これらのキーと値のオブジェクトを参照します。この参照が強力な参照である場合、ハッシュテーブルオブジェクト自体がまだ生きている限り、そこに含まれるキーと値のオブジェクトはリサイクルされません。生存期間が長いハッシュテーブルに多くのキー価値ペアが含まれている場合、最終的にJVMのすべてのメモリを消費する可能性があります。
この状況の解決策は、弱い参照を使用してこれらのオブジェクトを参照して、ハッシュテーブル内のキーと値の両方のオブジェクトを収集できるようにすることです。この一般的なニーズを満たすために、weakhashmapがJavaで提供されます。
サンプルコード:
パッケージcom.skywang.java; Import java.lang.ref.weakreference; public class weakreferencetest {public static void main(string [] args){weakreference ref = new MyDate()); System.gc(); }}実行結果:
OBJ [日付:1372142034360]はGCです
結果:JVMガベージコレクションが実行されると、弱い参照が終了します。
weakreference ref = new weakreference(new mydate()); system.gc();
相当:
mydate date = new MyDate(); //ガベージコレクションif(jvm.insuftiveer memory()){date = null; system.gc();}弱い参照とソフト参照の違いは、弱い参照のみを持つオブジェクトのライフサイクルが短いことです。ガベージコレクタースレッドがその管轄下にあるメモリ領域をスキャンするプロセス中に、弱い参照しかないオブジェクトが見つかると、現在のメモリスペースが十分かどうかにかかわらず、そのメモリはリサイクルされます。ただし、ガベージコレクターは優先度が非常に低いスレッドであるため、参照のみがあるオブジェクトについては必ずしも迅速に発見されるとは限りません。
参照キュー(リファレンスキュー)と組み合わせて、弱い参照を使用できます。弱い参照によって参照されるオブジェクトが収集されたガベージである場合、Java仮想マシンは、関連する参照キューに弱い参照を追加します。
4幻想の引用
Ghost Quotes〜また、Ghost Quotesを導入する前に、Javaが提供するオブジェクト終了メカニズムを最初に導入する必要があります。オブジェクトクラスにはファイナライズメソッドがあります。その設計の当初の意図は、オブジェクトが実際にリサイクルされる前に、いくつかのクリーニング作業を実行することです。 JavaはC ++ Destructorに類似したメカニズムを提供しないため、Finalizeメソッドを通じて実装されます。しかし、問題は、ゴミコレクターの実行時間が固定されていないため、これらのクリーニング作業の実際の実行時間を予測できないことです。 Phantomリファレンスはこの問題を解決できます。 Ghost Reference Phantomreferenceを作成するときは、参照キューを指定する必要があります。オブジェクトの最終メソッドが呼び出されると、オブジェクトのゴースト参照がキューに追加されます。キュー内の内容をチェックすることにより、オブジェクトをリサイクルする準備ができているかどうかがわかります。
ゴースト参照とそれらのキューの使用はまれであり、主に比較的細かいメモリ使用量制御を実装するために使用されます。これはモバイルデバイスにとって非常に意味があります。プログラムは、オブジェクトをリサイクルすることを決定した後、メモリを要求して新しいオブジェクトを作成できます。このようにして、プログラムによって消費されるメモリは、比較的少ない量で維持できます。
たとえば、次のコードは、バッファーの実装の例を示しています。
public class phantombuffer {private byte [] data = new byte [0];プライベートリファレンスキュー<byte []> queue = new ReferenceQueue <byte []>(); private phantomreference <byte []> ref = new phantomreference <byte []>(data、queue); public byte [] get(int size){if(size <= 0){throw new IllegalargumentException( "誤ったバッファサイズ"); } if(data.length <size){data = null; System.gc(); // Garbage Collectorを実行してください{queue.remove(); //このメソッドは、キューが非空白になるまでブロックされます。 // Ghost Referenceは自動的にクリアされません。Ref= nullを実行する必要があります。 data = new byte [size]; ref = new phantomreference <byte []>(data、queue); } catch(arturnedexception e){e.printstacktrace(); }}データを返します。 }}上記のコードでは、新しいバッファーが適用されるたびに、最初に以前のバッファーのバイト配列が正常にリサイクルされたことが保証されます。キューを参照する削除方法は、新しいゴースト参照がキューに追加されるまでブロックされます。ただし、このアプローチにより、ゴミコレクターが何度も実行されすぎるため、プログラムがスループットが低すぎる可能性があることに注意する必要があります。
サンプルコード:
パッケージcom.skywang.java; Import java.lang.ref.ReferenceQueue; Import java.lang.lang.ref.phantomreference; public class phantomreferencetest {public static void main(string [] args){referencequeue queue = new referencequeue(); Phantomreference Ref = new Phantomreference(new MyDate()、Queue); System.gc(); }}実行結果:
OBJ [日付:1372142282558]はGCです
結果は、インスタンス化後に錯覚参照が終了することを示しています。
ReferenceQueue queue = new ReferenceQueue(); Phantomreference Ref = new Phantomreference(new MyDate()、Queue); System.gc();
相当:
mydate date = new mydate(); date = null;