How to fix java.util.concurrent.CompletionException: java.lang.StackOverflowError

24.6k views Asked by At

I am writing a recursive code to contour the object according to the pixel value similarity. as you see below in the code i am using four threads work asynchronously, but at run time I receive the below posted errors and I do not know how to fix it.

Error received:

Exception in thread "main" java.util.concurrent.CompletionException: java.lang.StackOverflowError
at java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source)
at java.util.concurrent.CompletableFuture.completeThrowable(Unknown Source)
at java.util.concurrent.CompletableFuture$AsyncRun.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.StackOverflowError
at java.util.ArrayList.contains(Unknown Source)
at java.util.Collections$SynchronizedCollection.contains(Unknown Source)
at com.example.seedgrowtest.SeedGrowing$GrowSeedSWRun.growSeedsSW(SeedGrowing.java:234)
at com.example.seedgrowtest.SeedGrowing$GrowSeedSWRun.growSeedsSW(SeedGrowing.java:246)
at com.example.seedgrowtest.SeedGrowing$GrowSeedSWRun.growSeedsSW(SeedGrowing.java:246)

Code:

this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedSERun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedNWRun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedNERun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
this.growSeedFutureList = CompletableFuture.runAsync(new GrowSeedSWRun(this.saliencyMat, this.seedXY, this.seedVal), this.growSeedExecutor);
CompletableFuture.allOf(this.growSeedFutureList).join();

GrowSeedSWRun:

private class GrowSeedSWRun implements Runnable {

    private Mat saliencyMat = null;
    private double seedVal;
    private Point seedXY = null;

    public GrowSeedSWRun(Mat saliencyMat, Point seedXY, double seedVal) {
        // TODO Auto-generated constructor stub
        this.saliencyMat = saliencyMat;
        this.seedXY = seedXY;
        this.seedVal = seedVal;
    }
    public void run() {
        // TODO Auto-generated method stub
        this.growSeedsSW(this.saliencyMat, this.seedXY, this.seedVal);
    }

    private void growSeedsSW(Mat saliencyMat, Point seedXY, Double seedVal) {
        // TODO Auto-generated method stub
        int origX = (int) seedXY.x;
        int origY = (int) seedXY.y;

        if ( ((saliencyMat.get(origY, --origX) != null)) && ( withinRange(saliencyMat.get(origY, origX)[0]) )) {

            synchronized (grownSeedXYList) {//line number 234
                if (!grownSeedXYList.contains(new Point(origX, origY))) {

                    "+saliencyMat.get(origY, origX)[0]);

                    grownSeedXYList.add(new Point(origX, origY));
                } else {
                    Log.D(TAG, "growSeedsSW", "point: "+ new Point(origX, origY)+" contained in the list");
                }
            }

            this.growSeedsSW(saliencyMat, new Point(origX, origY), saliencyMat.get(origY, origX)[0]);//line number 246

            //check if this != null, because it might be the on the edge of the image
        } else if ( (saliencyMat.get(++origY, (int) this.seedXY.x) != null) && ( withinRange(saliencyMat.get(origY, (int) this.seedXY.x)[0]) )) {
            origX = (int) this.seedXY.x;

            synchronized (grownSeedXYList) {
                if (!grownSeedXYList.contains(new Point(origX, origY))) {

                     "+saliencyMat.get(origY, origX)[0]);

                    grownSeedXYList.add(new Point(origX, origY));
                }else {
                    Log.D(TAG, "growSeedsSW", "point: "+ new Point(origX, origY)+" contained in the list");
                }
            }
            this.growSeedsSW(saliencyMat, new Point(origX, origY), saliencyMat.get(origY, origX)[0]);
        }
    }
}
2

There are 2 answers

2
JP Moresmau On BEST ANSWER

Your growSeedsSW method is recursive, and it seems to exhaust the maximum stack size. Can you rewrite it in an iterative fashion? Otherwise you can try to make the stack size bigger with the Xss flag, as described in How to increase the Java stack size?.

0
Zephyr Guo On

You'd better check the following questions:

1.Your algorithm is recursive too deep. Out of the stack size.

2.Your algorithm has some issue that infinite recursion.