Есть ли способ переработать сложный объект Java, как только GC решил, что он недоступен

В C++ я использую объекты с подсчетом ссылок для реализации "автоматической" рециркуляции пула объектов

SmartPointer<ObjType> object = pool.getObject(); // hold reference

// ... do stuff with object over time.

object = nullptr; // that is when reference 
                  // count goes to 0

- Теперь у меня есть на объектах C++ метод "onFinalRelease()", который вызывается, когда счетчик достигает 0. Я могу переопределить это (по умолчанию delete(this)), чтобы автоматически перерабатывать объекты, а не уничтожать их.

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

SomeReference r = referenceQueue.getReference();

pool.recycle(r.takeBackUnusedObjectFromGC()); // ??????????????????????????

Это было бы очень приятно:)

4 ответа

Решение

Ты можешь использовать PhantomReference Чтобы сделать что-то вроде этого. Имейте интерфейсный (прокси) объект с (сильной, однонаправленной) ссылкой на дорогой объект. Также держите сильную ссылку на дорогой объект в вашем пуле управления. Держать PhantomReference к объекту интерфейса. Однажды PhantomReference встает на его ReferenceQueue Вы точно знаете, что дорогой объект не используется через интерфейсный объект (даже с учетом завершения). Теперь дорогой объект можно повторно использовать с новым интерфейсным объектом.

Однако, это, вероятно, не стоит того.

При подсчете ссылок есть четко определенное время, когда объект становится мусором - когда счетчик ссылок становится равным нулю. С помощью сборки мусора в Java нет гарантии, что данный объект когда-либо будет собирать мусор, даже если на него нет более сильных ссылок.

Внедрение собственного счетчика ссылок - лучшее решение, которое я могу придумать.

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

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

Другие вопросы по тегам