Ссылки на Java - PullRequest
       34

Ссылки на Java

3 голосов
/ 22 декабря 2009

Есть ли способ найти все ссылки на объект (в Java)?

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

Ответы [ 5 ]

6 голосов
/ 22 декабря 2009

Возможно, вы захотите взглянуть на различные ссылочные типы, предоставляемые Java: сильный, мягкий, слабый и фантомный .

Для кеша вы обычно помещаете ссылку в WeakReference или SoftReference и позволяете объекту собираться, когда не осталось более сильных ссылок.

5 голосов
/ 22 декабря 2009

У меня кеш объектов

Попробуйте использовать WeakHashMap вместо HashMap, чтобы схватить их всех.

Вот выдержка из API:

Реализация Map на основе хеш-таблицы с слабыми ключами . Запись в WeakHashMap будет автоматически удалена, если ее ключ больше не используется . Точнее говоря, наличие сопоставления для данного ключа не помешает тому, чтобы ключ был отброшен сборщиком мусора, то есть сделан финализируемым, финализированным и затем восстановленным. Когда ключ отбрасывается, его запись эффективно удаляется с карты, поэтому этот класс ведет себя несколько иначе, чем другие реализации Map.

2 голосов
/ 22 декабря 2009

Не существует опубликованного способа раскрытия такой информации. Пусть язык выполняет сборку мусора, задача поставщика JVM - реализовать его в соответствии с языком.

1 голос
/ 22 декабря 2009

Непонятно, что вы на самом деле пытаетесь сделать, поэтому я отвечу на ваш вопрос буквально.

Есть ли способ найти все ссылки на объект (в Java)?

Нет способа сделать это. Вы можете перейти от переменной или поля, содержащего ссылку, но Java не позволяет вам идти в другом направлении. Теоретически возможно делать подобные вещи, используя механизмы отладчика Java, но это было бы слишком сложно и дорого, чтобы быть практичным.

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

(Я предполагаю, что вы имеете в виду удаление объекта из кэша.) Опять же, я не понимаю, как вы могли бы сделать это в Java. Классы SoftReference и WeakReference позволят вам определить, был ли объект убран мусором , но нет, если будет мусором . Еще раз, подобные вещи могут быть теоретически осуществимы, но они слишком сложны и дороги, чтобы быть практичными.

Однако, если ваша настоящая цель состоит в том, чтобы реализовать кэш, который не мешает объектам собирать мусор, вы должны быть в состоянии сделать это с помощью WeakHashMap или путем создания собственного кэша, который соответствующим образом использует экземпляры WeakReference или SoftReference.

EDIT : Я полагаю, что вы могли бы также рассмотреть явную схему подсчета ссылок. Однако такую ​​схему будет трудно реализовать должным образом в Java.

В отличие от C ++, в Java не вызывается деструктор, когда переменная выходит из области видимости, или для атрибута, когда ее родительский объект подвергается сборке мусора. Для осуществления подсчета ссылок вам необходимо:

  • добавить явные значения счетчика приращения / уменьшения при всех присваиваниях ссылочным подсчитанным переменным и полям,
  • добавить блоки try { ... } finally, чтобы справиться со всеми возможными способами, которыми переменная со счетчиком ссылок может выйти из области видимости, и
  • и добавьте finalize методы к каждому классу, который имеет атрибут типа подсчитанного количества ссылок.

Теоретически это возможно, но (ИМО) слишком сложно понять все, кроме самых простых случаев. И (повторюсь), это гораздо сложнее сделать в Java, чем в C ++, потому что в Java нет деструкторов и перегрузки операторов присваивания.

0 голосов
/ 22 декабря 2009

Вы можете использовать схему подсчета ссылок. Имейте класс, который управляет доступом к этим объектам, так что вам нужно вызвать get () для класса (возможно, с некоторым аргументом), чтобы получить экземпляр - это должно увеличить счетчик для этого экземпляра. Когда ваш клиентский код завершен с объектом, он должен вернуть его, уменьшив счетчик. Тогда на все объекты с числом 0 будет ссылаться никто, кроме контейнера.

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

...