【Java】大量のデータを安全かつ高速に処理する方法について

Java

はじめに

Java の実務で。「数十万件のCSVデータを処理するバッチ」「DBから大量レコードを取得して集計する処理」等、大量データを扱う場面は少なくありません。こうした処理でよく発生するのが、

  • 本番で突然メモリ不足(OutOfMemoryError)
  • 開発環境では動くのに、本番では異常に遅い

といったトラブルです。
今回は、Javaで大量データを「安全かつ高速」に処理するための考え方と実装ポイントを、記載していきたいと思います。

他にも、体系的にJavaを学びたい方には以下の教材がおすすめです:

👉スッキリわかるJava入門 
👉スッキリわかるJava入門 実践編

 

Stream と for文、どちらを使うべきか

結論から言うと、以下のような使い分けとなります。

  • 可読性重視・中小規模データ :Stream
  • 性能重視・大量データ : for文

 

Streamのメリットとデメリット

list.stream()
    .filter(x -> x > 10)
    .map(x -> x * 2)
    .forEach(System.out::println);

 

メリット

  • 処理の流れが宣言的で読みやすい
  • 処理内容がシンプルに書ける

 

デメリット

  • 中間処理オブジェクトが増える
  • デバッグしづらい
  • 無意識に一度に全件メモリを載せてしまう

 

for文が向いている理由

for (int i = 0; i < list.size(); i++) {
    int value = list.get(i);
    if (value > 10) {
        System.out.println(value * 2);
    }
}
  • オブジェクト生成がStreamと比べて少ない
  • 処理の流れが追いやすい
  • ブレークポイントでデバッグしやすい

 

メモリを食い潰すNG例

例① 全件をListに溜め込む

件数が増えると一気にメモリを消費するため、一度に全件Listに溜め込む行為は、大量データを扱う上で、エラーとなる危険性が高いです。

List<Data> all = repository.findAll();

 

例② Streamでcollectしてから処理

Streamでcollectを行う場合、一度すべてメモリに保持が行われるため、こちらも大量データを扱う上で、エラーとなる危険性が高いです。

List<Result> results = list.stream()
    .map(this::convert)
    .collect(Collectors.toList());

 

例③ ログを出しすぎる

大量にrp具を出してしまうと、I/O処理が多くなり、処理時間が遅くなってしまいます。大量データを実施するさいはログの粒度を下げた設計とするのが良いです。

 

ページング処理で大量データを安全に扱う

大量データを安全に扱うには、一度に全て処理しないことを心がけます。

  • 一定件数ずつ処理
  • メモリ使用量が安定
  • 途中失敗しても再開しやすい
  • 処理時間の見積もりがしやすい

 

int pageSize = 1000;
int offset = 0;

while (true) {
    List<Data> page = repository.findPage(offset, pageSize);
    if (page.isEmpty()) {
        break;
    }

    for (Data data : page) {
        process(data);
    }

    offset += pageSize;
}

 

まとめ

大量データ処理は、速く書くことではなく、最後まで安全に処理できる設計を選ぶことです。Streamは可読性が高く便利ですが、大量データでは for文やページング処理の方が、メモリ・デバッグ・安定性の面で有利になるケースが多くあります。
今回の記事を参考に、大量データの処理を意識して処理を実施してみてください。

 

ドキュメント

【公式ドキュメント】
Java SE Specifications (oracle.com)

 

最後に

Javaの環境構築は、この記事を参照してみてください。
【開発環境構築】VS CodeでJavaを使用するための環境構築を実施する – SEもりのLog (selifemorizo.com)

以上、ログになります。
これからも継続していきましょう!!

Javaサーバーサイド関連
シェアする
おすすめIT本
良いコード/悪いコードで学ぶ設計入門

「ITエンジニア本大賞2023」技術書部門で大賞を受賞した本です。
・コードの可読性
・普段意識したほうが良いこと
・リファクタリング考え方
等、普段のコードを設計する際に意識することが書かれています。
コードのあるべき姿に迷ったら一度読んでみると良い本です。

仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん

Dockerって何?となったときに私が最初に読んだ本です。
Dockerがどんな仕組みで動いているのか、コマンドでは何を命令しているのかを理解できるように、イラストを多用して説明しています。

1冊ですべて身につくJavaScript入門講座

「ITエンジニア本大賞2024」技術書部門で大賞を受賞した本です。
私が次に読もうと思っている本なのでおすすめとして挙げておきたいと思います。

コメント

タイトルとURLをコピーしました