#java #postgresql #memory-leaks #resultset #printwriter
#java #postgresql #утечки памяти #набор результатов #printwriter
Вопрос:
У меня есть огромный набор результатов, включающий, скажем, 1 миллион строк. Обычно я использую следующий фрагмент, чтобы записать их в файл, тогда как у меня всегда не хватает памяти. Существуют ли какие-либо эффективные способы устранения этой проблемы?
PrintWriter writer = new PrintWriter(filename, "UTF-8");
iteration -> { writer.println(a single string); }
writer.close();
Комментарии:
1. Исследуйте буферизацию. Таким образом, вы потребляете столько памяти, сколько хотите.
2. Попробуйте сбросить программу записи после печати.
3. Не делайте весь файл сразу. Разбейте его на куски.
4. Предполагается, что @MaxMega close() выполняет функцию flush() .
5. Вы действительно имеете в виду, что весь результат находится в одной (!) строке (строка)?
Ответ №1:
Поскольку вы сказали ResultSet, я так понимаю, это происходит из базы данных? Сначала используйте потоковый набор результатов. Драйвер JDBC MySQL любит буферизировать все строки в памяти, и с 1M (или 1B) строками это может быть проблемой.
Если вы хотите, чтобы это масштабировалось, делайте это поточным способом. Пусть один поток, производитель, считывает строки из результирующего набора, а другой, потребитель, записывает строки в файл. Что-то вроде ArrayBlockingQueue отлично подходит для этого. Если потребитель не может идти в ногу с производителем, запустите блокировку и подождите, пока потребитель догонит. Этот подход занимает меньше памяти и работает быстрее, поскольку ваш ввод-вывод выполняется параллельно.
Комментарии:
1. То же самое верно и для PostgreSQL, кстати. Вы захотите установить FetchSize .