Java 8, using .parallel in a stream causes OOM error -


in book java 8 in action, section 7.1.1, authors state stream can benefit parallel processing adding function .parallel(). provide simple method called parallelsum(int) illustrate this. curious see how worked executed code:

package lambdasinaction.chap7;  import java.util.stream.stream;  public class parallelplay {      public static void main(string[] args) {         system.out.println(parallelsum(100_000_000));     }      public static long parallelsum(long n) {         return stream.iterate(1l, -> + 1)                 .limit(n)                 .parallel()                 .reduce(0l, long::sum);     } } 

to surprise, received error:

exception in thread "main" java.lang.outofmemoryerror     @ sun.reflect.nativeconstructoraccessorimpl.newinstance0(native method)     @ sun.reflect.nativeconstructoraccessorimpl.newinstance(unknown source)     @ sun.reflect.delegatingconstructoraccessorimpl.newinstance(unknown source)     @ java.lang.reflect.constructor.newinstance(unknown source)     @ java.util.concurrent.forkjointask.getthrowableexception(unknown source)     @ java.util.concurrent.forkjointask.reportexception(unknown source)     @ java.util.concurrent.forkjointask.invoke(unknown source)     @ java.util.stream.sliceops$1.opevaluateparallellazy(unknown source)     @ java.util.stream.abstractpipeline.sourcespliterator(unknown source)     @ java.util.stream.abstractpipeline.evaluate(unknown source)     @ java.util.stream.referencepipeline.reduce(unknown source)     @ lambdasinaction.chap7.parallelplay.parallelsum(parallelplay.java:15)     @ lambdasinaction.chap7.parallelplay.main(parallelplay.java:8) caused by: java.lang.outofmemoryerror: java heap space     @ java.util.stream.spinedbuffer.ensurecapacity(unknown source)     @ java.util.stream.nodes$spinednodebuilder.begin(unknown source)     @ java.util.stream.abstractpipeline.copyinto(unknown source)     @ java.util.stream.abstractpipeline.wrapandcopyinto(unknown source)     @ java.util.stream.sliceops$slicetask.doleaf(unknown source)     @ java.util.stream.sliceops$slicetask.doleaf(unknown source)     @ java.util.stream.abstractshortcircuittask.compute(unknown source)     @ java.util.concurrent.countedcompleter.exec(unknown source)     @ java.util.concurrent.forkjointask.doexec(unknown source)     @ java.util.concurrent.forkjoinpool$workqueue.runtask(unknown source)     @ java.util.concurrent.forkjoinpool.runworker(unknown source)     @ java.util.concurrent.forkjoinworkerthread.run(unknown source) 

i running java 1.8.0_45 on windows 7, sp1 four-core processor. what's going on?

here create infinite stream , limit afterwards. there known problems processing infinite streams in parallel. in particular there's no way split task equal parts effectively. internally heuristics used not suitable every task. in case it's better create finite stream using longstream.range:

import java.util.stream.longstream;  public class parallelplay {      public static void main(string[] args) {         system.out.println(parallelsum(100_000_000));     }      public static long parallelsum(long n) {         return longstream.rangeclosed(1, n).parallel().sum();     } } 

in case stream engine knows beginning how many elements have, can split task effectively. note using longstream more effecient have no unnecessary boxing.

in general avoid infinite streams if can solve task finite ones.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -