2017-11-17 1 views
-1

私は巨大なデータセットを扱っています。私は並列処理が必要ですが、私はjava8 stream apiに問題があります。私はそのようなコードを単純化しました。 parallelStream()stream()に変更すると私のプログラムは最大メモリとして16GBを使用します。java8 parallelstream()は、stream()と比較してメモリ使用量が多くなります

以下のコードでは、32GBのメモリでは不十分です。これを改善する方法はありますか?

List<Class2> result = querySource 
.parallelStream() 
.map(m -> { 
    List<Class1> rows = getSourceByDB(m); 
    return rows; 
}) 
.map(m -> { 
    List<Class2> result = Common.convertToClass2(m); 
    return result; 
}).flatMap(f -> f.stream()) 
.collect(Collectors.toList()); 

答えて

0

パラレルストリームの使用common fork-join thread pool。パラレルストリームは、並列化を利用してすべてのCPUコアを利用するCPU集約型のプログラムを使用している場合に使用すると効果的です。例指定されたリスト内のすべての数を追加し、与えられたリスト内の素数を見つけます。

複数のリソース/外部リソースを使用する場合は、並列ストリームはお勧めできません。このシナリオを考えてみましょう.1つのスレッドがRESTfulなサービスにアクセスして情報を取得し、内部で奇数の合計を計算するその他のスレッドを取得します。第2のスレッドは実行を完了し、他のスレッドを待つ(すなわち、それぞれが異なるリソースを必要とするにもかかわらず、他のスレッドをブロックする)。

膨大なメモリを消費する理由は、前述の一般的なfork-joinスレッドプールのシナリオ、つまりスレッドが別のスレッドを待機しているためです。外部リソースが関与している場合はParallel Streamを使用しないでください。

+0

ありがとうございます。ところで、いくつかの調査の後、私はtimeseriesデータを扱っています。 1時間分のデータを60個のチャンクで取得しようとすると、30 GBのチャンクでチャンクするだけで十分です。しかし、java8のparallelstream()APIやexecutorserviceを使用して60個のチャンクを並列化しようとすると、64 GBのヒープが簡単に埋め尽くされます。それから、巨大なGC休止時間のためにエラーが発生します。私はJVMの問題があると思う。メモリをクリアすることはできません。アドバイスはありますか? –

関連する問題