Когда объект Class получает мусор? - PullRequest
4 голосов
/ 04 сентября 2011

Мне было интересно, может ли кто-нибудь сказать мне, когда объект Java Class собирает мусор.Мой вариант использования - это кеш (Map<Class<?>, Class<?>[]>), который содержит иерархию классов объектов.

Например:

(короткая) иерархия String.class будет (по убыванию):String.class -> Object.class.Допустимая запись кэша для этого типа будет [KEY: String.class, VALUE: {String.class, Object.class}].

Полагаю, String.class является плохим примером, поскольку класс String.class должен собираться мусором ....

Iнужен этот кеш для сериализации проекта, над которым я работаю.При написании объекта моей системе нужна иерархия этого объекта для выбора правильных «кодеков (сериализаторов)».Сбор иерархии для каждого объекта вызовет некоторые издержки, которые не являются необходимыми.Но тогда я подумал про утечки памяти.Вероятно, объекты классов могут быть собраны мусором (чего я не знаю), который не будет работать при использовании сильных ссылок в моем кэше.

Как вы думаете, WeakHashMap будет достаточно?Или я должен использовать что-то вроде:

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

Что вы думаете об этой проблеме?

Ответы [ 3 ]

2 голосов
/ 04 сентября 2011

Не вдаваясь в подробности сборки мусора классов в Java, я не думаю, что вам нужно беспокоиться вообще: сами объекты класса не нужно собирать, чтобы предотвратить утечку памяти, чтобы выполнить то, что вы хотите.В конце концов, для java.lang.String будет только один экземпляр класса.Поэтому, если вы поместите ссылку на String.class в Map (или любую другую структуру данных), вы не создадите новый экземпляр класса String, а просто ссылку на существующий.

Каккак только ваш Map выйдет из области видимости, весь Map будет иметь право на сборку мусора.

0 голосов
/ 04 сентября 2011

Классы - это сборщик мусора одновременно с загрузчиком классов.Поэтому не сильные ссылки важны, если вы хотите, чтобы ваш код работал в присутствии временных загрузчиков классов.

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

Это почти работает.Вы не можете иметь массив универсального типа.Вместо этого я предлагаю использовать List.

Это скорее интернирование, а не кэширование.В этом случае это не должно иметь большого значения, так как объем памяти, используемой на ключ, крошечный по сравнению с классом.Если вы действительно хотите кэш, вам нужно будет использовать ReferenceQueue для выселения и что-то вроде:

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

(Если вы хотите, углы можно очистить, введя классы [с поведением], которые могут бытьиспользуется для ключа и значения.)

0 голосов
/ 04 сентября 2011

Вы не можете сказать точное время, когда объект собирается сборщиком мусора, даже при вызове сборщика мусора (Runtime.getRuntime (). Gc ();).

Кроме того, использование WeakHashMap для кэшированияобычно плохой выбор, поскольку слабые ссылки используются только для ключей, а не для значений.Просто Google, вы найдете много полезных статей, например,

Наконец, вы должны проверить, действительно ли вам нужно кэширование (например, с помощью профилировщика, такого как JVisualVM), поскольку вы используете объекты String и Class ...

...