Regression (b92): OOM on filter/limit operation on unbound/parallel stream
Mallwitz, Christian
christian.mallwitz at Commerzbank.com
Tue Jun 4 05:02:13 PDT 2013
Hi,
Re-reporting problem for build 92: the filter/limit on unbound, parallel stream operation behaves very weird. How weird? Well:
- the serial version uses about 16M of heap, the parallel gobbles up all of the 1GB defined as max
- it throws an OOM after running for hours while it is __NOT__ garbage collecting much but
- the filter predicate is called on millions of elements more than what can be observed using a serial stream
- I can't observe any parallelism (based on number of cores and system load - 4 cores and only 25% load)
I'm using 1.8.0-ea-lambda-nightly-h4544-20130526-b92-b00 on a Windows XP 32 bit machine - VM args: -mx1g -XX:+PrintCommandLineFlags -verbose:gc -XX:+PrintGCTimeStamps
My test program tries to find the first 283,146 prime numbers (which are all below 4,000,000). It executes the filter/limit operation on a serial stream first and prints out numbers tested for primality occasionally.
Thanks
Christian
package com.snuffbumble.lambda;
import java.util.stream.LongStream;
import java.util.stream.Stream;
public class OOM {
public static void main(String... ignored) {
// first 283_146 primes are all < 4_000_000
firstNPrimes(283_146, getIteratorBasedStream(false)); // only minor GC - max heap 16M
firstNPrimes(283_146, getIteratorBasedStream(true)); // full GC - up to max heap 1GB and subsequent OOM
}
private static Stream<Long> getIteratorBasedStream(boolean produceParallelStream) {
Stream<Long> s = LongStream.iterate(1L, n -> n + 1L).boxed();
return produceParallelStream ? s.parallel() : s;
}
private static void firstNPrimes(int n, Stream<Long> stream) {
System.out.println(String.format("firstNPrimes (%8d, %5b): %8d", n, stream.isParallel(),
stream
.filter(OOM::isPrime)
.limit(n) // limit after primality test
.count()));
}
private static long start_millis = System.currentTimeMillis();
private static long max_n_seen = 3_999_970L;
private static boolean isPrime(long n) {
if (n >= max_n_seen) {
System.out.println(String.format("%.3f: %d", (System.currentTimeMillis() - start_millis)/1000.0, n));
max_n_seen = n + (n/20L); // new max_n_seen 5% larger than current n
}
if (n <= 1) { return false; }
if (n == 2) { return true; }
if (n % 2 == 0) { return false; }
for (int i = 3; i <= (int) Math.sqrt(n); i += 2) { if (n % i == 0) return false; }
return true;
}
}
More information about the lambda-dev
mailing list