WeakHashMap
最近、Javaのデータ構造について知りました。
ただし、それが何を意味するのかわかりません。通常使用されなくなったときにマッピングをガベージコレクションします。プログラムでキーを使用しなくなることをデータ構造はどのようにして知るのですか?長い間キーを参照しないとどうなりますか?
WeakHashMap
最近、Javaのデータ構造について知りました。
ただし、それが何を意味するのかわかりません。通常使用されなくなったときにマッピングをガベージコレクションします。プログラムでキーを使用しなくなることをデータ構造はどのようにして知るのですか?長い間キーを参照しないとどうなりますか?
ただし、それが何を意味するのかわかりません。通常使用されなくなったときにマッピングをガベージコレクションします。
わかった。通常の状況では、ガベージコレクターを実行すると、プログラムが使用できなくなったオブジェクトが削除されます。専門用語は「到達不能オブジェクト」であり、プログラムの実行ではオブジェクトへの参照を取得する方法がないことを意味します。到達不能なオブジェクトは、次のGCサイクルで収集される可能性があります...またはそうではありません。いずれにせよ、それはもはやアプリケーションの関心事ではありません。
この場合、はキー1WeakHashMap
を参照するために呼び出される特別なクラスを使用します。弱参照は、間接ポインター(ポインターを保持しているオブジェクトへのポインター)のように機能するオブジェクトです。ガベージコレクターが参照を破ることができるという興味深い特性があります。つまり、含まれている参照を。に置き換えます。そして、ルールは、オブジェクトへの弱い参照は、オブジェクトが通常の(強い)参照またはソフト参照のチェーンを介して到達できなくなったことにGCが気付いたときに壊れることです2。WeakReference
null
「もはや通常使用されていない」という表現は、実際には、キーオブジェクトが強くまたはソフトに到達できなくなったことを意味します。つまり、強力な参照および/またはソフト参照のチェーンを介して。
プログラムでキーを使用しなくなることをデータ構造はどのようにして知るのですか?
はしませんWeakHashmap
。むしろ、キーに強く到達できないことに気付くのはGCです。
通常のトラバーサルの一部として、GCはすべての強く到達可能なオブジェクトを見つけてマークします。次に、すべてのWeakReference
オブジェクトを調べて、それらが参照しているオブジェクトがマークされているかどうかを確認し、マークされていない場合はそれらを壊します。SoftReference
(またはそのようなもの...実際のGCの実装を見たことがありません。また、PhantomReference
オブジェクトも処理する必要があるという事実によって複雑になっています。)
唯一の関与WeakHashmap
は次のとおりです。
WeakReference
キーのオブジェクトを作成して使用し、WeakReferences
GCによってキーがクリアされたハッシュテーブルエントリを消去します。長い間キーを参照しないとどうなりますか?
弱参照を破るべきであると決定するための基準は、時間ベースではありません。
ただし、キーが削除されるかどうかにタイミングが影響する可能性があります。たとえば、キーは1)強く参照されなくなる、2)マップから取得される、3)到達可能な変数に割り当てられて、もう一度強く参照されるようにすることができます。キーに強く到達できないウィンドウでGCが実行されない場合、キーとそれに関連する値はマップに残ります。(これはあなたが起こりたいことです...)
1-実装の詳細:最近のJavaリリースでは、弱参照は実際にはEntry
キーではなくマップの内部オブジェクトを参照しています。これにより、壊れた参照をマップからより効率的に削除できます。詳細については、コードを参照してください。
2-ソフト参照は、ヒープメモリが不足している場合にGCが中断できる一種の参照です。
Javaには、あるオブジェクトがまだ使用されているかどうかを言語がコードに伝えることができる参照システムがあります。参照を使用して、あるオブジェクトが使用されなくなった、または使用できなくなったと明確に識別されたことを検出し、それに応じてアクションを実行できます。 このチュートリアルでは、リファレンスの使用方法に興味がある場合に備えて、リファレンスについて詳しく説明します。
内部的には、WeakHashMap
これらの参照を使用して、特定のキーが使用できなくなったことを自動的に検出する可能性があります。実装は、これらのオブジェクトをハッシュテーブルから削除して、スペースを占有しないようにすることができます。
お役に立てれば!
JVMガベージは、次の順序で収集されます。
WeakReference
SoftReference
通常、ガベージコレクターは、参照されていないオブジェクトのみをガベージコレクションします。
オブジェクトへの弱参照は、ガベージコレクターに関する限り、参照としてカウントされません。ガベージコレクターは、それらを収集する場合と収集しない場合があります。通常、メモリが不足しない限りそれらを収集しませんが、保証はありません。
JVMのメモリが不足しそうな場合、ガベージコレクタはソフト参照されたオブジェクトを収集します。ソフト参照オブジェクトがガベージコレクションされる前に、すべての弱い参照オブジェクトがガベージコレクションされます。
SoftReferenceのjavadocから:
ソフトに到達可能なオブジェクトへのすべてのソフト参照は、仮想マシンが
OutOfMemoryError
「通常の使用」という特定の表現について尋ねる質問を読んだので、強参照と弱参照についてすでに知っていると仮定します。通常の使用とは、弱いハッシュマップに、他のデータ構造によっても(強く)参照されるキーが含まれている場合を指します。キーへの強い参照が少なくとも1つ存在するのは、「通常の使用」です。この他のデータ構造がキーを参照している限り、キーをガベージコレクションすることはできません。他のデータ構造に到達できなくなると(そのデータ構造へのポインタが存在しなくなると)、キーも到達不能になります。それへの唯一の参照はマッピングの弱いものであるため、それはもはや通常の使用ではありません。ガベージコレクターは最終的にそれを再利用でき、マッピングは消えます。
これは、サブクラス化によってタイプCを拡張したいが、できない場合に発生します。たとえば、Cが多くの実装を持つインターフェイスである場合です。この問題を回避するには、キータイプCの弱いハッシュマップと、新しいクラスEにラップされて追加される新しいフィールドを使用します。Cインスタンスを作成するたびに、Eインスタンスを作成し、そのペアをマップに追加します。次に、Cインスタンスの存続期間中に新しいフィールドにアクセスするために使用されます。Cインスタンスがガベージになると、マッピングとEインスタンスもガベージになります。ハッシュマップが弱いため、これは自動的に行われます。そうでない場合は、ガベージコレクターのない言語でストレージを明示的に解放する必要があるのと同じ方法で、手動でクリーンアップする必要があります。