Java: оптимизация gc для больших буферов

Приложение, над которым я работаю, одновременно фильтрует огромные файлы с использованием памяти кучи только для буферов BufferedReader (~ 8 ГБ для нескольких файлов). Имеется достаточно памяти для выполнения одной операции фильтрации, после чего буферы удаляются:

try (BufferedReader br1 = new BufferedReader(new InputStreamReader(
      new FileInputStream(file1), encoding), 1_000_000_000);

    BufferedReader br2 = new BufferedReader(new InputStreamReader(
      new FileInputStream(file2), encoding), 1_000_000_000);

    ...

    BufferedReader br8 = new BufferedReader(new InputStreamReader(
      new FileInputStream(file8), encoding), 1_000_000_000);

) {

  // ... filtering

}

Какими должны быть оптимальные настройки GC для этой конфигурации использования памяти?

Текущие параметры JVM довольно стандартны:

-Xms31g
-Xmx31g
-XX:+UseCompressedOops
-XX:NewSize=12g

Версия Java - 9.

Вам действительно нужен такой большой буфер? Кажется, по крайней мере, на 3 порядка больше, чтобы иметь какое-либо реальное применение. В конце концов, размер буфера по умолчанию составляет 8 КБ, что обеспечивает очень хорошую производительность.

Kayaman 11.04.2018 12:52

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

Joop Eggen 11.04.2018 13:12

@Kayaman Размер буфера способствует повышению производительности и работоспособности диска при одновременном чтении нескольких файлов.

Denis Kulagin 11.04.2018 15:48

..и так как все знают, что чем больше, тем лучше, внутренний буфер 1GB для BufferedReader как минимум на 1000 лучше, чем внутренний буфер 1MB, не говоря уже о жалком буфере 8KB, который он имеет по умолчанию. Вероятно, вам следует увеличить размер буфера. Я имею в виду, что вы все равно можете удвоить это количество, прежде чем оно достигнет предела размера массива.

Kayaman 11.04.2018 17:29

Вы исправляете это не с того конца. Вы должны использовать большой (r) целевой массив при вызове Reader.read. Это делает использование BufferedReader полностью устаревшим. Кроме того, количество фактических операций ввода-вывода определяется размером буфера декодера InputStreamReader. Единственный способ контролировать это - использовать FileChannel и Channels.newReader(…).

Holger 13.04.2018 14:12

С другой стороны, как намекнул Юп Эгген, использование ввода-вывода с отображением памяти может решить эту проблему еще лучше.

Holger 13.04.2018 14:15
0
6
60
0

Другие вопросы по теме