Java-эквивалент GC.SuppressFinalize

1

Есть ли у Java эквивалент.Net GC.SuppressFinalize?

В.Net SuppressFinalize используется в шаблоне dispose, чтобы избежать относительно высоких затрат на завершение до тех пор, пока объект явно размещен. Аналогичные затраты относятся к Java, но, похоже, не имеют SuppressFinalize.

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

Есть ли эквивалент SuppressFinalize в Java? Если нет, можно ли его приблизить, используя доступные инструменты (например, ReferenceQueue)?

Показать ещё 1 комментарий
Теги:
garbage-collection
finalizer

2 ответа

1
Лучший ответ

Для Java нет встроенного метода "GC.SuppressFinalize". Но IDiposable шаблон будет полезен для вас, чтобы решить эту проблему.

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

1

Я придумал возможное обходное решение для того, чтобы на Java не было эквивалента, поскольку избегается стоимость финализаторов: используйте кеш.

  1. Имейте объект со сменным элементом обратного вызова:

    public final class Finalizer {
      public Runnable onFinalizer;
      @Override
      protected void finalize() {
        if (onFinalizer != null) {
          onFinalizer.run();
        }
      }
    }
    
  2. Имейте их коллекцию:

    Stack<Finalizer> finalizerCache = new Stack<>();
    
  3. При необходимости захватить:

    this.finalizer = finalizerCache.isEmpty() ? new Finalizer() : finalizerCache.pop();
    this.finalizer.onFinalizer = () -> { my special cleanup code; };
    
  4. Отменить при необходимости:

    void cancel() {
      this.finalizer.onFinalizer = null;
      if (finalizerCache.size() < 100) {
        finalizerCache.push(this.finalizer);
      }
      this.finalizer = null;
    }
    

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню