Подтвердить что ты не робот

Каков наилучший способ очистки объекта в Java?

У нас нет деструктора в Java, как у нас на С++.

Q1. Как очистить любой объект в java.

Q2. Есть ли альтернатива блоку finally.

Q3. Иногда нам приходится вызывать явно инициализацию/завершение кода третьей стороны из нашего класса, например.

public classs MyClass{
    public MyClass(){
        ThirdPartyInitialize();
    }

    protected void finalize(){
        ThirdPartyTerminate();
    }
}

Правильно ли это?

4b9b3361

Ответ 1

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

Блок finally предназначен для выполнения действий, если исключение выбрано из блока try или нет, и это лучшее место для выполнения очистки. Как правило, вы только очищаете неъектные ресурсы, такие как открытые потоки.

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

Итак, 1) используйте блоки finally для освобождения ресурсов, отличных от объекта. 2) пусть сборщик мусора очистит объектные ресурсы. 3) вы можете намекнуть сборщику мусора, что вы сделали с объектом, установив его на null если он используется в долгосрочном методе.

Ответ 2

Вы также можете добавить shutdown hook в свою программу, если ваша программа также выключается:

//add shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        ThirdPartyTerminate();
    }
});

Ответ 3

Лучший способ очистки объектов - просто удалить объект.

Наконец, блоки могут быть абстрагированы с использованием идиомы Execute Around.

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

Ответ 4

A1. Если вам нужно uninitialize объект, тогда Dispose pattern - путь.

A2. С точки зрения управления ресурсами этого нет. Следует отметить, однако, что блок finally не является детерминированным управлением ресурсами.

A3. Да, это правильный путь.

Ответ 5

Вот хорошее представление о финализаторах.

Ответ 6

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


C a = new C(); //create an object of class C and assign it to 'a'
a = new C(); //create another object of class C and assign it to 'a'. The older object is no longer referred to. It is now eligible for GC.

Есть лучшие альтернативы finalize() в зависимости от того, насколько finalize() помогает вашей ситуации.

Часто рекомендуется использовать такой метод, как close() или disposeResources() в API, который позволит вызывающему пользователю помочь самому очистить API. Например, класс java.sql.Connection делает это. Это лучше, чем метод finalize(), поскольку JVM вызовет метод finalize(). Часто метод finalize() запускается потоком с низким приоритетом в JVM, что приводит к некоторым странным ошибкам.

В случае класса Connection ожидание JVM для выполнения финализации оказывается дорогостоящим во многих приложениях, поскольку база данных может принимать только так много соединений за раз. Поэтому большинство программистов вызову close() явно в объекте Connection.

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


try
{
 ThirdPartyInitialize();
 // use third party component in this try block
}
finally
{
 ThirdPartyTerminate();
}

Это похоже на то, как класс Connection также используется в большинстве ситуаций.

Ответ 7

Два варианта синтаксического сахара:

1) В Lombok есть @Cleanup аннотация в Lombok, которая в основном напоминает деструкторы С++ (более):

@Cleanup
ResourceClass resource = new ResourceClass();

2) Существует также try-with-resources. Например:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
}

Ответ 8

Финализация используется аналогично деструктору, но если вы используете try... finally block для ресурсов, тогда вы можете открыть ресурс, а в блоке finally вы закроете ресурс.

Блок finally всегда вызывается, когда блок завершается, либо нормально, либо через исключение.

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

Последний блок - лучший подход.

Ответ 10

Ваши объекты в Java действительно никогда не нуждаются в "Очистке", GC Just работает. Почти каждый раз, когда я видел someObject = null в коде, это был тот, кто не знал, что они делают. Для этого есть теоретический пример, но это действительно крайний случай и, как правило, лучше обрабатывается другими способами, как недавно добавленная попытка с ресурсом.

Если у вас есть внешний ресурс, который нужно очистить, когда объект больше не используется, это другое дело.

Существуют классы "Reference", которые будут содержать специальный тип ссылки для вашего класса - он не остановит сбор мусора, но может уведомить вас о том, когда класс собран мусором (через обратный вызов, если хотите). Найдите WeakReference, PhantomReference и т.д.

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