ホームページ  >  記事  >  Java  >  Java の弱参照の学習と理解

Java の弱参照の学習と理解

WBOY
WBOY転載
2023-04-25 18:25:09942ブラウズ

何——弱い参照とは何ですか?

Java の弱参照は、具体的には java.lang.ref.WeakReference クラスを指します。まず、公式ドキュメントの説明を見てみましょう:

弱参照オブジェクトが存在しても、それが指すオブジェクトがガベージ コレクターによってリサイクルされるのを妨げることはありません。弱参照の最も一般的な使用法は、正規化マッピング (ハッシュ テーブルなど) を実装することです。

ある時点でガベージ コレクターが、オブジェクトが弱到達可能である (つまり、そのオブジェクトを指している現在のポイントがすべて弱参照である) と判断すると、ガベージ コレクターはすべての弱参照をクリアします。オブジェクトへの参照を作成し、後でリサイクルされるように、弱く到達可能なオブジェクトをファイナライズ可能としてマークします。同時に、または後で、ガベージ コレクターは、クリアされたばかりの弱参照を、弱参照オブジェクトの作成時に指定された参照キュー (Reference Queue) に置きます。

実際には、Java には 4 種類の参照があり、強いものから弱いものの順に、強参照、ソフト参照、弱参照、仮想参照です。以下に、弱参照を除く他の 3 種類の参照を簡単に紹介します:

  • 強参照: 通常、new を通じて新しいオブジェクトを作成すると、返される参照は強参照です。オブジェクトは一連の強参照を通じて到達可能です。強参照可能ですが、リサイクルされません。

  • ソフト参照: ソフト参照 参照と弱参照の違いは次のとおりです。オブジェクトが弱い参照によって到達可能な場合、現在のメモリが十分であるかどうかに関係なくリサイクルされますが、ソフト参照によって到達可能なオブジェクトは、メモリが不足している場合にリサイクルされるため、ソフト参照の方が優れています。弱い参照 参照は「より強い」

  • ファントム参照: ファントム参照は Java で最も弱い参照です。非常に壊れやすいため、仮想参照を介して参照先のオブジェクトを取得することさえできません。仮想参照の唯一の目的は、仮想参照が指すオブジェクトがリサイクルされるときに、仮想参照自体が参照キューに追加されて記録されることです。尖った物体はリサイクルされました。

理由——なぜ弱い参照を使用するのでしょうか?

次のシナリオを考えてみましょう: 製品を表す Product クラスが存在します。このクラスは拡張できないように設計されており、現時点では各製品に番号を追加したいと考えています。 。 1 つの解決策は、HashMap を使用することです。 Product オブジェクトがメモリ内に存在する必要がなくなった場合 (たとえば、この製品が販売された場合)、それを指す参照が productA であると仮定すると、この時点で productA の値を null に代入します。ただし、この時点では、productA が過去に指した Product オブジェクトは明らかに HashMap によって参照されているため、リサイクルされません。

したがって、この場合、Product オブジェクトを本当にリサイクルしたい場合は、その強参照を null に割り当てるだけでは十分ではなく、対応するエントリを HashMap から削除する必要もあります。明らかに、「不要になったエントリを HashMap から削除する」という作業を自分たちで完了する必要はありません。HashMap 内のキーのみが Product オブジェクトを参照する場合、対応する Product オブジェクトはリサイクルできることをガベージ コレクターに伝えたいのです。 。明らかに、弱い参照の前述の定義によれば、弱い参照を使用すると、この目標を達成するのに役立ちます。 HashMap のキーとして Product オブジェクトを指す弱参照オブジェクトを使用するだけで済みます。

方法——弱い参照を使用するにはどうすればよいですか?

上で紹介したシナリオを例に挙げると、HashMap のキーとして Product オブジェクトを指す弱参照オブジェクトを使用します。この弱参照オブジェクトを次のように定義するだけです。

製品 productA = 新しい製品(...);
WeakReferenceweakProductA = 新しい WeakReference<>(productA);

ここで、オブジェクトweakProductAが参照されると、それはProductオブジェクトproductAを指します。では、weakProduct を通じてそれが指す Product オブジェクト productA を取得するにはどうすればよいでしょうか?非常に簡単で、次のコードのみが必要です:

Product product =weakProductA.get();

実際、この場合、Java class ライブラリは WeakHashMap クラスを提供します。このクラスを使用する場合、そのキーは当然弱参照オブジェクトであるため、元のオブジェクトを手動でラップする必要はありません。このようにして、productA が null になると (参照する Product がメモリ内に存在する必要がなくなったことを示します)、弱参照オブジェクトweakProductA は Product オブジェクトを指すため、この時点では対応する Product オブジェクトは明らかに弱いです。したがって、それを指す弱参照はクリアされ、Product オブジェクトはすぐにリサイクルされ、それを指す弱参照オブジェクトは参照キューに入ります。

参照キュー

参照キューの概念を簡単に紹介します。実際、WeakReference クラスには 2 つのコンストラクターがあります:

//创建一个指向给定对象的弱引用
WeakReference(T referent) 
//创建一个指向给定对象并且登记到给定引用队列的弱引用
WeakReference(T referent, ReferenceQueue<? super T> q)

2 番目のコンストラクターが ReferenceQueue 型のパラメーターを提供していることがわかります。このパラメーターを提供することで、作成された弱参照オブジェクトを参照キューに登録します。ガベージ コレクターによってクリアされると、参照キューに送信され、これらのクリアされた弱参照オブジェクトを統一的に管理できるようになります。

以上がJava の弱参照の学習と理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。