Как использовать сборку мусора для удаления файлов? - PullRequest
6 голосов
/ 29 июня 2009

Привет! Я использую много временных файлов в Java, и моя проблема в том, что они не удаляются.

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

1 - используя File tmp = File.createTempFile (), конечно, я могу сказать tmp.deleteOnExit (), но если вещь запускается в службе, то единственный выход - это когда происходит сбой (случается редко) или когда сбой системы (например, когда диск полностью заполнен временными файлами и опрокидывает кластер ... упс!)

В идеале, созданные экземпляры собираются в некоторый момент сборщиком мусора, и, поскольку в приложении МНОГО времени простоя, было бы просто здорово, если бы GC мог, ну, закончить его очистку и фактически удалить файл на диске, а также при разыменовании экземпляра из памяти.

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

Короче говоря, могу ли я использовать сборщик мусора для очистки системных ресурсов (т.е. файлов)?


Спасибо всем за ваши ответы. Я принял предложение Кристоффера, так как его было проще всего реализовать, и именно это я и сделал.

Полагаю, из-за того, что уборка через столько лет заставила меня забыть об основных делах, которые мне приходилось выполнять, в трудные времена в хорошие времена C ++.

Ответы [ 7 ]

3 голосов
/ 29 июня 2009

Конечно, вы можете. Вопрос в том, действительно ли ты хочешь:)

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

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

2 голосов
/ 29 июня 2009

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

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

  • Напишите обработчик событий, когда ваша программа закрывается, чтобы очистить все файлы, которые вы открыли во время текущего сеанса.
  • Напишите процедуру, которая будет запускаться при запуске вашей программы, которая удалит все временные файлы в этой папке старше 24 часов.

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

2 голосов
/ 29 июня 2009

Возможно, вы захотите посмотреть PhantomReference :

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

1 голос
/ 29 июня 2009

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

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

Обе вещи случаются особенно часто, если Java запускается с большим размером кучи - вещь, которая на стороне сервера не является чем-то необычным.

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

1 голос
/ 29 июня 2009

Сборка мусора - неправильное пространство имен для этого типа обработки информации.

Для обработки временных файлов должно быть достаточно следующего пункта.

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

  2. DeleteOnExit, который вы должны использовать.

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

0 голосов
/ 29 июня 2009

Сборщик мусора - это не место для освобождения такого рода ресурсов. Пожалуйста, посмотрите эти две статьи ниже о том, как выпустить ресурсы в Java http://c2.com/cgi/wiki?ReleasingResourcesInJava А также проблемы производительности с финализаторами Java. Они могут дать некоторое понимание и понимание того, как его следует использовать. http://www.enyo.de/fw/notes/java-gc-finalizers.html

0 голосов
/ 29 июня 2009

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

Но финализаторы не вызываются каким-либо предсказуемым образом, поэтому я бы вообще не рекомендовал этого.

...