Есть ли способ переработать сложный объект 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 может быть полезен для этого.