Потребление памяти параллельным потоком Scala

Я написал приложение Scala (2.9.1-1), которому необходимо обработать несколько миллионов строк из запроса к базе данных. Я преобразовываю ResultSetв Stream, используя метод, показанный в ответе на один из моих предыдущих вопросов:

class Record(...)

val resultSet = statement.executeQuery(...)

new Iterator[Record] {
  def hasNext = resultSet.next()
  def next = new Record(resultSet.getString(1), resultSet.getInt(2), ...)
}.toStream.foreach { record => ... }

, и это сработало очень хорошо.

Поскольку тело замыкания foreachочень интенсивно использует ЦП, и как свидетельство практичности функционального программирования, если я добавлю .parперед foreach замыкания выполняются параллельно без каких-либо других усилий, за исключением того, чтобы убедиться, что тело замыкания является потокобезопасным (оно написано в функциональном стиле без изменяемых данных, кроме печати в потокобезопасный журнал).

Однако меня беспокоит потребление памяти. Является ли .parпричиной загрузки всего набора результатов в ОЗУ, или параллельная операция загружает только столько строк, сколько у нее активных потоков? Я выделил 4G для JVM (64-разрядный с -Xmx4g), но в будущем я буду запускать его на еще большем количестве строк и беспокоиться о том, что в конечном итоге я получу нехватку памяти.

Существует ли лучший шаблон для выполнения такой параллельной обработки функциональным образом? Я показывал это приложение своим коллегам как пример ценности функционального программирования и многоядерных машин.

6
задан Community 23 May 2017 в 12:14
поделиться