StreamOpFlag.* and OutOfMemoryError when going parall
Brian Goetz
brian.goetz at oracle.com
Wed Dec 5 10:34:15 PST 2012
There's a good reason you are struggling with it -- this API is not
intended for "casual" builders of streams. The intention is that 99.9%
of users will never write code to call the Streams.stream() method
directly; they will use arrays, collections, generators, or other
packaged providers of streams.
A safe default is 0. You can OR together the IS_ version of the flags
if you know something about the nature of your stream. You probably
want IS_ORDERED if you want to represent a stream for which the order of
elements means something (e.g., a range generator, a List, an array, etc.)
The reason it is failing with OOME is that the parallel implementation
of limit() computes the entire results rather than operating fully
lazily. While it would be preferable to operate more lazily, a lazy
parallel implementation of operations like limit is not trivial. We
hope to improve this in the future.
On 12/5/2012 1:18 PM, Christian Mallwitz wrote:
> Hi,
>
> Using lambda-8-b67-linux-i586-03_dec_2012 I'm trying to compute n (not
> necessarily the first n) prime numbers:
>
> import java.util.*;
> import java.util.function.*;
> import java.util.stream.*;
>
> public class LambdaExample3 {
>
> public static boolean isPrime(long n) {
> if (n <= 1) { return false; }
> if (n == 2) { return true; }
> for (int i = 2; i <= Math.sqrt(n) + 1; i++) { if (n % i == 0)
> return false; }
> return true;
> }
>
> public static void main(String[] args) {
>
> Stream<Long> stream =
> Streams.parallel(Streams.spliteratorUnknownSize(new Iterator<Long>() {
> private long n = 0;
> @Override public boolean hasNext() { return true; }
> @Override public Long next() { return ++n; }
> }),
> // fails with OutOfMemoryError
> // StreamOpFlag.toStreamFlags(StreamOpFlag.NOT_SIZED,
> StreamOpFlag.INITIAL_OPS_VALUE)
> // fails with OutOfMemoryError
> // StreamOpFlag.NOT_SIZED
> // works, but no speed-up to non-parallel version
> StreamOpFlag.INITIAL_OPS_VALUE
> );
>
> stream
> .filter(LambdaExample3::isPrime)
> .limit(300000)
> .forEach(l -> { /*System.out.println(l);*/ });
> }
> }
>
> I'm struggling with the StreamOpFlag parameter. What should I pick?
> INITIAL_OPS_VALUE seems to work but isn't running anything in parallel
> (at least it is not faster than the serial version). NOT_SIZED isn't
> working but failing miserably with an OutOfMemoryError. IS_PARALLEL
> is not needed because I already use parallel() - should specifying
> IS_PARALLEL and using Streams.stream() supposed to go parallel as
> well?
>
> Is the OutOfMemoryError caused by a bug? The OutOfMemoryError is
> reported from a fork/join pool thread so at least it is going
> parallel? Am I missing something?
>
> Thanks
> Christian
>
More information about the lambda-dev
mailing list