Изменить нестатическую переменную на статическую переменную - PullRequest
0 голосов
/ 21 февраля 2019

Я читаю о GC и читаю, что, когда объект получает право на сборку мусора, GC должен запустить на нем метод finalize.Метод finalize гарантированно выполняется только один раз, поэтому ГХ помечает объект как завершенный и дает ему отдых до следующего цикла.

В методе финализации вы можете технически «воскресить» объект,например, присваивая его статическому полю.Объект снова станет живым и не будет иметь права на сборку мусора, поэтому GC не будет собирать его во время следующего цикла.

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

Я нахожу это захватывающим.Однако, если моя переменная не является статической, как я могу изменить ее на статическую в методе finalize?

Помните:

Объект получает право на сборку мусора или сборщик мусора, если оннедоступен из любых живых потоков или статических ссылок.Так что взломать это добавить объект к статическому ресурсу внутри метода finalize, и это предотвратит сборку мусора только один раз.Метод finalize защищен, поэтому может быть переопределен подклассами, независимо от того, находятся они в одном пакете или нет.

Это опасная практика, и нет необходимости использовать внутри кода приложения.

1 Ответ

0 голосов
/ 21 февраля 2019

Изменение определения переменной во время выполнения не легко, а в некоторых случаях почти невозможно.Могут быть некоторые неприятные трюки с отражением, которые могут включать встроенную компиляцию, загрузку классов и т. Д., Но вы не должны этого делать.Изменение переменной со статической на нестатическую или наоборот также потребовало бы перемещения данных в хранилище и устранения потенциальных коллизий, поэтому не делайте этого.

В любом случае переменные - это просто ссылки и воскрешение объектавам просто нужно создать новую ссылку из живого потока.Это может быть сделано с некоторой коллекцией, на которую ссылается статическая переменная и к которой добавляется ссылка this.

Пример (только для иллюстрации, не используйте ее, если вы действительно не знаете, что выделают и имеют вескую причину для ):

class NastyResurrector {
  public static Collection<Object> RESURRECTED_OBJECTS = ...;// use whatever collection implementation you like
}

Тогда в finalize() вы бы позвонили NastyResurrector.RESURRECTED_OBJECTS.add(this), и там у вас есть ссылка.

Однако яЯ процитирую из источника вашего вопроса (вопрос Q11):

Остерегайтесь, что этот уродливый взлом должен использоваться, только если вы действительно знаете, что делаете

Это, на мой взгляд, самый важный вынос.

...