Привет, у меня есть код, который использует блок
RandomAccessFile file = new RandomAccessFile("some file", "rw");
FileChannel channel = file.getChannel();
// some code
String line = "some data";
ByteBuffer buf = ByteBuffer.wrap(line.getBytes());
channel.write(buf);
channel.close();
file.close();
но особенность приложения заключается в том, что мне нужно сгенерировать большое количество временных файлов, в среднем более 4000 (используется для вставок Hive в многораздельную таблицу).
Проблема в том, что иногда я ловлю исключение
Failed with exception Too many open files
во время работы приложения.
Интересно, есть ли способ сообщить ОС, что файл уже закрыт и больше не используется, почему
channel.close();
file.close();
не уменьшает количество открытых файлов. Есть ли способ сделать это в коде Java?
Я уже увеличил максимальное количество открытых файлов в
#/etc/sysctl.conf:
kern.maxfiles=204800
kern.maxfilesperproc=200000
kern.ipc.somaxconn=8096
Обновление:
Я попытался устранить проблему, поэтому я разделил код, чтобы исследовать каждую его часть (создавать файлы, загружать в куст, удалять файлы).
Использование класса «Файл» или «RandomAccessFile» завершается неудачей с исключением «Слишком много открытых файлов».
Наконец я использовал код:
FileOutputStream s = null;
FileChannel c = null;
try {
s = new FileOutputStream(filePath);
c = s.getChannel();
// do writes
c.write("some data");
c.force(true);
s.getFD().sync();
} catch (IOException e) {
// handle exception
} finally {
if (c != null)
c.close();
if (s != null)
s.close();
}
И это работает с большим количеством файлов (проверено на 20 КБ с размером 5 КБ каждый). Сам код не выдает исключение как предыдущие два класса.
Но производственный код (с ульем) все же имел исключение. И кажется, что причиной этого является соединение улья через JDBC.
Я буду расследовать дальше.