Java 8 stream – stackoverflow exception

Run the following code example to:

import java.util.stream.IntStream;
import java.util.stream.Stream;

public class TestStream {

    public static void main(String[] args) {
        Stream<String> reducedStream = IntStream.range(0,15000)
            .mapToObj(Abc::new)
            .reduce(
                Stream.of("Test"),(str,abc) -> abc.process(str),(a,b) -> {throw new IllegalStateException();}
        );
        System.out.println(reducedStream.findFirst().get());
    }

    private static class Abc { 
        public Abc(int id) {
        }

        public Stream<String> process(Stream<String> batch) {
            return batch.map(this::doNothing);
        }

        private String doNothing(String test) {
            return test;
        }
    }
}

What causes this problem? Which part of this code is recursive and why?

Solution

Your code has no recursive loops You can test the intstream range (i.e. 1 or 100) with a smaller number In your case, this is the actual stack size limit that causes the problem As pointed out in some comments, its process is process

Each call on the stream creates a new wrapper stream around the original file‘ The findfirst() 'method requests elements from the previous stream, which in turn requires previous stream elements Since the stream is not a real container, it is just a pointer to the result element

The packaging explosion occurs in the "accumulator" (STR, ABC) of the reduce method – > ABC process(STR)”. The implementation of this method creates a new stream wrapper on the result (STR) of the previous operation, enters the next iteration, and creates a new wrapper on the result (STR)) So the accumulation mechanism is one of a wrapper (recursion) rather than an appender (iteration) Therefore, creating a new stream of actual (flattened) results instead of referring to potential results will prevent the explosion, i.e

public Stream<String> process(Stream<String> batch) {
        return Stream.of(batch.map(this::doNothing).collect(Collectors.joining()));
    }

This method is just an example, because your original example has no meaning, because it does nothing, and this example is not It is just an example It basically flattens the elements of the stream returned by the map method into a single string, and creates a new stream on this specific string, rather than on the stream itself, which is different from your original code

You can adjust the stack size using the "- XSS" parameter that defines the stack size of each thread The default value depends on the platform. See also the question 'what is the maximum depth of the Java call stack?' However, be careful when adding. This setting applies to all threads

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>