torutkのブログ

ソフトウェア・エンジニアのブログ

Stream APIで大きなファイルを読み込むと

Java SE 7で導入されたNIO2のFilesクラスでreadAllLinesメソッドを使って大きなファイルを読むと、ヒープメモリを圧迫またはOutOfMemoryErrorを起こします。

List<String> lines = Files.readAllLines(Paths.get(args[0]), StandardCharsets.UTF_8);

Windows 7 64bit(12GBメモリ)で、Java SE 8 64bit版上でヒープメモリサイズのオプションを指定せずに(デフォルト)実行し、8GBのファイルを上述コードで読み込ませたところOutOfMemoryErrorが発生しました。

Java SE 8で導入されたStream APIを使って大きなファイルを読み込むとどうか試してみました。

try (BufferedReader reader = Files.newBufferedReader(Paths.get(args[0]), Charset.forName("UTF-8"))) {
    reader.lines()
          .map(s -> s.split(" ")[0])
          .distinct()
          .sorted()
          .forEach(System.out::println);
} catch (IOException e) {
    throw new UncheckedIOException(e);
}

8GBのファイルを読み込みましたがヒープメモリ使用量は数十MBから300MBを増減しつつ処理を終えました。

なるほど、遅延されることのメリットが1つ見えました。