@ user183717 - указанный вами код явно не является всем соответствующим кодом.Например, эти "..." и тот факт, что File.delete()
на самом деле не вызывается в этом коде.
Когда объект потока собирается мусором, его финализатор закрывает базовый дескриптор файла.Таким образом, тот факт, что удаление работает только при добавлении вызова System.gc()
, является убедительным доказательством того, что вашему коду каким-то образом не удалось закрыть какой-то поток для файла.Вполне возможно, что объект потока отличается от того, который открыт в опубликованном вами коде.
Правильно написанный код обработки потока использует блок finally
, чтобы обеспечить закрытие потоков независимо от того, что.Например:
Reader reader = new BufferedReader(new FileReader(file));
try {
// do stuff
} finally {
try {
reader.close();
} catch (IOException ex) {
// ...
}
}
Если вы не следуете этому шаблону или чему-то подобному, есть хороший шанс, что есть сценарии, где потоки не всегда закрываются.Например, в вашем коде, если один из вызовов read
или write
вызвал исключение, вы пропустите операторы, закрывающие потоки.
Это [то есть вызов System.gc();
] надежный?
Нет.
- JVM может быть настроен на игнорирование вызова
gc()
вашего приложения. - Нет гарантии, что потерянный потокбудет недоступен ... пока.
- Нет гарантии, что вызов
System.gc()
заметит, что поток недоступен.Гипотетически, объект потока может быть сохранен, а вызов System.gc()
может только собрать пространство Eden. - Даже если GC обнаружит, что поток недоступен, нет гарантии, что GC запустит финализаторнемедленно.Гипотетически, запуск финализаторов может быть отложен ... на неопределенное время.
Или есть лучшее решение?
Да.Исправьте ваше приложение, чтобы правильно закрыть его потоки.