Есть ли деструктор для Java?

559
задан Yoon5oo 25 July 2018 в 14:45
поделиться

13 ответов

Поскольку Java является собравшим "мусор" языком, Вы не можете предсказать, когда (или даже если) объект будет уничтожен. Следовательно нет никакого прямого эквивалента деструктора.

существует унаследованный метод, названный finalize, но это называют полностью на усмотрение сборщика "мусора". Таким образом для классов, которые должны явно убраться, соглашение состоит в том, чтобы определить близкий , метод и использование завершают только для проверки исправности (т.е. если близкий не был назван, делают это теперь и регистрируют ошибку).

был вопрос, который метал икру, всестороннее обсуждение завершают недавно, так, чтобы обеспечил больше глубины при необходимости...

497
ответ дан Community 25 July 2018 в 14:45
поделиться

Самый близкий эквивалент деструктору в Java эти , завершают () метод. Большая разница для традиционного деструктора - то, что Вы не можете быть уверены, когда это назовут, так как это - ответственность сборщика "мусора". Я настоятельно рекомендовал бы тщательно читать на этом перед использованием его, так как Ваши типичные шаблоны RAIA для дескрипторов файлов и так далее не будут работать надежно с, завершают ().

1
ответ дан Nik 25 July 2018 в 14:45
поделиться

Эти finalize() функция является деструктором.

Однако это не должно обычно использоваться, потому что это вызывается после GC, и Вы не можете сказать, когда это произойдет (если когда-либо).

, Кроме того, требуется больше чем один GC для освобождения объектов, которые имеют finalize().

необходимо попытаться вымыться в логических местах в коде с помощью эти try{...} finally{...} операторы!

4
ответ дан Sai Kishore 25 July 2018 в 14:45
поделиться

Нет, никакие деструкторы здесь. Причина состоит в том, что все объекты Java являются выделенной "кучей" и собрали "мусор". Без явного освобождения (т.е. оператор delete C++) нет никакого разумного способа реализовать реальные деструкторы.

Java действительно поддерживает финализаторы, но они предназначены, чтобы использоваться только в качестве гарантии для объектов, содержащих дескриптор к собственным ресурсам как сокеты, дескрипторы файлов, дескрипторы окна, и т.д. Когда сборщик "мусора" собирает объект без финализатора, это просто отмечает регион памяти как свободный и вот именно. Когда объект имеет финализатор, он сначала копируется во временное местоположение (помните, мы собираем "мусор" здесь), тогда он ставится в очередь в waiting-to-be-finalized очередь, и затем поток Финализатора опрашивает очередь с очень низким приоритетом и выполняет финализатор.

, Когда приложение выйдет, остановки JVM, не ожидая незаконченных объектов, которые будут завершены, таким образом, там практически никакие гарантии, что Ваши финализаторы будут когда-либо работать.

107
ответ дан ddimitrov 25 July 2018 в 14:45
поделиться

Нет, java.lang.Object#finalize является самым близким, можно добраться.

Однако то, когда (и если) это называют, не гарантируется.
См.: java.lang.Runtime#runFinalizersOnExit(boolean)

9
ответ дан Mr. Polywhirl 25 July 2018 в 14:45
поделиться

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

3
ответ дан I GIVE CRAP ANSWERS 25 July 2018 в 14:45
поделиться

Я полностью соглашаюсь на другие ответы, говорить для не доверия выполнению завершает.

В дополнение к try-catch-finally блокам, можно использовать Runtime#addShutdownHook (представленный в Java 1.3) для выполнения заключительных очисток в программе.

, Который не является тем же, поскольку деструкторы , но можно реализовать рычаг завершения работы, регистрирующий объекты прослушивателя, на которых методах очистки (закрывают персистентные соединения с базой данных, удаляют блокировки файла, и так далее) может быть вызван - вещи, которые обычно делались бы в деструкторах . Снова - это не замена для деструкторов, но в некоторых случаях, можно приблизиться к требуемой функциональности с этим.

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

14
ответ дан Agi Hammerthief 25 July 2018 в 14:45
поделиться

Если это - просто память, Вы волнуетесь по поводу, не делать. Просто доверяйте GC, он делает достойное задание. Я на самом деле видел что-то об этом являющийся столь эффективным, что для производительности могло быть лучше создать "кучу" крошечных объектов, чем использовать большие массивы в некоторых случаях.

4
ответ дан John Nilsson 25 July 2018 в 14:45
поделиться

Использование завершает () , методов нужно избежать. Они не надежный механизм для ресурса, моются, и возможно вызвать проблемы в сборщике "мусора" путем злоупотребления их.

при требовании вызова освобождения в объекте скажите для высвобождения средств, используйте явный вызов метода. Это соглашение видно в существующих API (например, Closeable, Graphics.dispose () , Widget.dispose () ) и обычно называется через попытку/наконец.

Resource r = new Resource();
try {
    //work
} finally {
    r.dispose();
}

Попытки использовать склонный объект должны выдать исключение на этапе выполнения (см. IllegalStateException).

<час>

РЕДАКТИРОВАНИЕ:

я думал, если бы все, что я сделал, должно было только разыменовать данные и ожидать сборщика "мусора" для сбора их, то там не была бы утечка памяти, если бы мой пользователь неоднократно вводил данные и нажимал кнопку сброса?

Обычно все, что необходимо сделать, разыменовывают объекты - по крайней мере, это - способ, которым это, как предполагается, работает. Если Вы волнуетесь по поводу сборки "мусора", проверяете [TM] сборка "мусора" Java SE 6 HotSpot Виртуальной машины, Настраивающаяся (или эквивалентный документ для Вашей версии JVM).

26
ответ дан McDowell 25 July 2018 в 14:45
поделиться

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

Из Вашего сообщения это не кажется, что Вы пытаетесь реализовать метод сброса в целях объектного повторного использования (верный?). Ваши объекты содержат какой-либо другой тип ресурсов, которые должны быть очищены (т.е. потоки, которые должны быть закрыты, какие-либо объединенные или одолженные объекты, которые должны быть возвращены)? Если бы единственной вещью, по поводу которой Вы волнуетесь, является память dealloc тогда, я пересмотрел бы свою структуру объекта и попытался бы проверить, что мои объекты сам содержавшие структуры, которые будут очищены во время GC.

0
ответ дан tyler 25 July 2018 в 14:45
поделиться

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

Вы можете быть уведомлены после того, как объект был уничтожен с помощью java.lang.ref. PhantomReference (на самом деле, говоря это был уничтожен, может быть немного неточным, но если фантомная ссылка на него ставится в очередь тогда, это больше не восстанавливаемо, который обычно составляет то же самое). Общее использование:

  • Выделяют ресурс (ресурсы) в Вашем классе, который должен быть разрушен в другой объект помощника (обратите внимание, что, если все Вы делаете, закрывает соединение, которое является общим падежом, Вы не должны писать новый класс: соединение, которое будет закрыто, было бы "объектом помощника" в этом случае).
  • при создании основного объекта создайте также PhantomReference к нему. Или имейте, это относится к новому объекту помощника или настроило карту от объектов PhantomReference до их соответствующих объектов помощника.
  • После того, как основной объект собран, PhantomReference ставится в очередь (или скорее это может быть поставлено в очередь - как финализаторы нет никакой гарантии, которой это когда-либо будет, например, если VM выйдет тогда, то это не будет ожидать). Удостоверьтесь, что Вы обрабатываете его очередь (или в специальном потоке или время от времени). Из-за твердой ссылки на объект помощника еще не был собран объект помощника. Также - независимо от того, что очистка, которую Вы любите на объекте помощника, затем отбрасывает PhantomReference, и помощник будет в конечном счете забран также.

существует, также завершают (), который похож на деструктор, но не ведет себя как один. Это обычно - не хороший вариант.

6
ответ дан Steve Jessop 25 July 2018 в 14:45
поделиться

Прошу прощения, если это отклоняется от основной темы, но в документации java.util.Timer (SE6) говорится:

«После того, как последняя живая ссылка на объект Timer исчезнет, ​​и все невыполненные задачи завершили выполнение, поток выполнения задачи таймера корректно завершается (и становится объектом сборки мусора). Однако это может занять произвольно много времени. По умолчанию поток выполнения задачи не выполняется как поток демона, поэтому он способный удерживать приложение от завершения. Если вызывающий хочет быстро завершить поток выполнения задачи таймера, вызывающий должен вызвать метод отмены таймера ... "

Я хотел бы вызвать отмену, когда класс, владеющий таймером, теряет свой последняя ссылка (или иммедиталеская перед). Здесь надежный деструктор мог бы сделать это за меня. Комментарии выше указывают на то, что это, наконец, плохой выбор, но есть ли элегантное решение? Тот факт, что «... способный предотвратить завершение работы приложения ...» не является привлекательным.

6
ответ дан 22 November 2019 в 22:11
поделиться

Если вы пишете Java-апплет, вы можете переопределить метод "destroy ()" апплета. Это ...

  * Вызывается браузером или программой просмотра апплетов для информирования
 * этот апплет, что он восстанавливается и должен уничтожить
* любые ресурсы, которые он выделил. Метод stop ()
 * всегда будет вызываться перед destroy ().

Очевидно, это не то, вы , но может быть то, что ищут другие люди.

1
ответ дан 22 November 2019 в 22:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: