При обсуждении финализируемых объектов в Java обычно обсуждаются общие косвенные издержки, возникающие, когда финализируемые объекты (и связанные с ними ресурсы) не могут быть быстро удалены сборщиком мусора.
На данный момент меня больше интересует, какова фактическая прямая стоимость финализации, как с точки зрения памяти, так и с точки зрения времени выделения объекта. Я видел косвенные ссылки на существование такой стоимости в ряде мест, например, В статье Oracle о проблемах сохранения памяти при финализации отмечается:
Когда выделяется
obj
, JVM внутренне записывает, чтоobj
является финализируемым. Обычно это замедляет быстрый путь распределения, который есть у современных JVM.
Как JVM регистрирует, что экземпляр объекта может быть финализирован, и каковы затраты памяти и производительности на это?
Для тех, кто интересуется моим конкретным приложением:
Мы производим и храним миллионы невероятно легких предметов; добавление одного указателя к этим объектам невероятно затратно, поэтому мы проделали немало работы, чтобы удалить из них указатели, вместо этого используя меньшие числовые идентификаторы, упакованные в подмножество битов поля. Распаковка номера позволяет получить общее неизменяемое свойство с этим идентификатором из пула, в котором они хранятся с использованием карты.
Остается вопрос, как справиться со сборкой мусора для значений свойств, которые больше не используются.
Одной из рассмотренных стратегий является использование подсчета ссылок; когда объекты создаются и извлекают объединенный идентификатор для значения, счетчик ссылок для этого значения увеличивается; когда он больше не используется, он должен быть уменьшен.
Одним из вариантов обеспечения этого уменьшения является добавление следующего метода финализации:
public void finalize() {
Pool.release(getPropertyId());
}
Однако, если само действие финализации означает необходимость сохранения дополнительного указателя на объект, первоначальные затраты на финализацию будут считаться высокими для этого приложения. Если это означает, что должны быть выделены дополнительные объекты, это почти наверняка будет слишком дорого... отсюда мой вопрос: каковы прямые первоначальные затраты на финализацию?
finalize()
будет вызван - или? - person vikingsteve   schedule 08.05.2015n
слабые или временные ссылочные объекты, если естьn
объектов для очистки, и JVM должна делать заметки о каждой такой слабой ссылке, чтобы их можно было поставить в очередь, когда соответствующий объект является мусором собрал. - person Theodore Murdock   schedule 08.05.2015WeakReference
, чтобы у вас не было лишних объектов. Но даже в этом случае эта дополнительная информация обычно считается значительно более дешевой, чем доработка. - person Louis Wasserman   schedule 08.05.2015java.lang.ref.Reference
(FinalReference), поэтому они не могут быть дешевле, но их поведение сложнее. Более того, HotSpot JVM не использует встроенное выделение объектов, имеющих нетривиальный финализатор. - person apangin   schedule 08.05.2015