Подсчет ссылок в Java - PullRequest
       3

Подсчет ссылок в Java

8 голосов
/ 17 октября 2010

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

Объекты являются общими, поэтому простой try { ... } finally { close(); } не подойдет.

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

К сожалению, поиск в Google для «подсчета ссылок в Java» не приносит никаких полезных результатов. Поэтому мой вопрос: есть ли какие-либо ресурсы (статьи, примеры кода, библиотеки), которые могут помочь в подсчете ссылок?

Ответы [ 3 ]

8 голосов
/ 17 октября 2010

Не зависит от сборщика мусора.Он специально разработан, чтобы не быть надежным.

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

3 голосов
/ 17 октября 2010

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

Но тот же метод (то есть WeakReference) сделаю;просто закройте ручку, когда референт становится null.Однако вам может потребоваться подкласс на заказ WeakReference с дополнительной ссылкой на дескриптор файла, чтобы вы могли закрыть его (иначе у вас не будет доступа к дескриптору файла).Например:

public class WeakFileReference extends WeakReference<File> {

  private final File  handle;
  public WeakFileReference(File handle, ReferenceQueue q) {
    super(handle, q);
    this.handle = (File)handle.clone();
  }
}

Я не проверил это полностью и не могу быть уверен, как вы используете объект File в своей программе: я предполагаю, что вы делитесь экземпляром File вокруг.

1 голос
/ 21 октября 2018

К сожалению, поиск в Google для «подсчета ссылок в java» не приносит никаких полезных результатов.

К сожалению, это продолжает оставаться верным 8 лет спустя.

Но больше нет!Я вытащил Нетти бит подсчета ссылок, немного отшлифовал их и превратил в отдельную библиотеку almson-refcount .

Базовая ссылкаПодсчет функциональности прост и понятен.Существует один базовый класс, ReferenceCountedObject.У него есть один переопределяемый метод, destroy.Он предоставляет retain и release, которые управляют внутренним счетчиком ссылок, используя поточно-безопасный и эффективный AtomicFieldUpdater.release вызовет destroy в том же потоке, и из-за семантики упорядочения памяти между различными вызовами release вам не нужно беспокоиться о поточной безопасности вашего destroy даже в многопоточномприложение.Класс реализует AutoCloseable и предоставляет метод close, который просто вызывает release.Это позволяет использовать его в try-with-resources.

Нет механизма финализации, который пытается вызвать destroy в случае, если вы забудете вызвать release!Завершение представляет большие проблемы, включая проблемы параллелизма и даже преждевременное завершение, особенно в общем случае.(Если вы настаиваете на наличии финализаторов, вы все равно можете использовать их или более производительные java.lang.ref.Cleaner.)

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

Основные изменения, внесенные в Netty:

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