4

ClassJavaオブジェクトがガベージ コレクションされるタイミングを教えてくれる人がいるかどうか疑問に思っていました。Map<Class<?>, Class<?>[]>私の使用例は、オブジェクトのクラス階層を保持するキャッシュ ( ) です。

例えば:

の (短い) 階層はString.class(降順): String.class->になりObject.classます。このタイプの有効なキャッシュ エントリは[KEY: String.class, VALUE: {String.class, Object.class}].

String.classString.class はガベージ コレクションする必要があるため、これは悪い例だと思います。

私が取り組んでいるシリアル化プロジェクトには、このキャッシュが必要です。オブジェクトを作成するとき、システムは正しい「コーデック (シリアライザー)」を選択するために、このオブジェクトの階層を必要とします。各オブジェクトの階層を収集すると、不要なオーバーヘッドが発生します。しかし、その後、メモリリークについて考えました。おそらく、クラスオブジェクトはガベージコレクションされる可能性があります(これはわかりません)が、キャッシュで強い参照を使用している場合は機能しません。

WeakHashMap で十分だと思いますか? または、次のようなものを使用する必要がありますか:

Map<WeakReference<Class<?>>, WeakReference<Class<?>>[]> ?

この問題についてどう思いますか。

4

3 に答える 3

2

Java でのクラス ガベージ コレクションの詳細に立ち入ることなく、まったく心配する必要はないと思います。目的を達成するためにメモリ リークを防ぐために、クラス オブジェクト自体を収集する必要はありません。結局のところ、 の Class インスタンスは 1 つしか存在しませんjava.lang.String。したがって、への参照をString.class(Mapまたはその他のデータ構造) に入れる場合、String クラスの新しいインスタンスを作成するのではなく、既存のインスタンスへの参照を作成するだけです。

範囲外になるとすぐMapに、全体Mapがガベージ コレクションの対象になります。

于 2011-09-04T10:43:18.467 に答える
0

ガベージ コレクタ (Runtime.getRuntime().gc();) を呼び出した場合でも、オブジェクトがガベージ コレクションされる正確な時刻を知ることはできません。

さらに、弱い参照はキーに対してのみ使用され、値に対しては使用されないため、キャッシュに WeakHashMap を使用することは、通常は悪い選択です。ググるだけで、役立つ記事がたくさん見つかります。

最後に、String オブジェクトと Class オブジェクトを使用しているため、本当にキャッシュが必要かどうかを確認する必要があります (たとえば、JVisualVM などのプロファイラーを使用)。

于 2011-09-04T10:54:08.290 に答える
0

クラスは、クラス ローダーと同時にガベージ コレクションされます。そのため、一時的なクラス ローダーの存在下でコードを動作させたい場合は、非強参照が重要です。

Map<WeakReference<Class<?>>, WeakReference<Class<?>>[]>

これはほとんど機能します。ジェネリック型の配列を持つことはできません。代わりにa を使用することをお勧めしListます。

これは、キャッシングではなく一種のインターンです。この場合、キーごとに使用されるメモリの量はクラスと比較して小さいため、それほど重要ではありません。本当にキャッシュが必要な場合はReferenceQueue、エビクションなどに使用する必要があります。

Map<SoftReference<WeakReference<Class<?>>>, List<WeakReference<Class<?>>>>

(必要に応じて、キーと値に使用できる [動作を伴う] クラスを導入することで、角度をクリーンアップできます。)

于 2011-09-04T12:56:41.523 に答える