В принципе, вы правильно поняли. Но оставшиеся в живых объекты не сразу копируются в старое поколение. Вместо этого они копируются в пространство Survivor, где им необходимо пережить настраиваемое количество сборок мусора, прежде чем они будут переведены в старое поколение.
Но фундаментальное предположение верно. Эффективность снижается, когда объекты выживают дольше, чем необходимо, и необходимость вызывать finalize()
продлевает срок службы объекта.
Принципиальное решение состоит в том, чтобы сделать это исключительным случаем. Это даже рассматривается в спецификации :
Для эффективности реализация может отслеживать классы, которые не переопределяют метод finalize класса Object, или переопределяет еготривиальным образом.
Например:
protected void finalize() throws Throwable {
super.finalize();
}
Мы рекомендуем реализациям рассматривать такие объекты как имеющие финализатор, который не переопределяетсяи завершить их более эффективно, как описано в §12.6.1.
В случае JVM HotSpot он распознает, когда метод, унаследованный Object
, не был переопределен иликогда он был переопределен пустым методом. Afaik, единственный супер-вызов не всегда распознается, но для вашего собственного языка, возможно, будет возможно его распознать.
Так что для большинства объектов в Java, finalize()
не нужно вызывать, так как это никак не влияет и никогда не вызывается. Это решает проблему расширенного срока службы, поскольку теперь оно применяется только к нескольким объектам.
Необходимость сканирования мертвых объектов устраняется благодаря наличию специального ссылочного объекта, который создается только для тех объектов, которые имеют нетривиальныефинализатор, который сам по себе остается доступным. Таким образом, это все еще только достижимые объекты, которые должны быть проверены. Более подробную информацию можно найти в этом ответе .