java.lang.Stackoverflowerror: stack size 1038KB

Asked

Viewed 319 times

0

I’m making an algorithm that converts one leaving it in shades of gray.

I could do it using for but I’d like to do it recursively.


Using for (This working well)

//BUTTON - ON CLICK . . .
public void go(View v){
    //BM_3 É UM BITMAP, VARIAVEL GLOBAL QUE JÁ POSSUI UMA IMAGEM EM SEU CONTEUDO . . .
    bm_3 = bm_3.copy(Bitmap.Config.ARGB_8888, true);

    for (int x = 0; x < bm_3.getWidth(); x++){
        for (int y = 0; y < bm_3.getHeight(); y++) {

            String hex = Integer.toHexString(bm_3.getPixel(x, y));

            if(hex.length() == 8) {
                String hexX = "#" + convert_Hex_to_grey("" + hex.charAt(0) + hex.charAt(1),
                                                        "" + hex.charAt(2) + hex.charAt(3),
                                                        "" + hex.charAt(4) + hex.charAt(5),
                                                        "" + hex.charAt(6) + hex.charAt(7));

                bm_3.setPixel(x, y, Color.parseColor(hexX));
            }
        }
    }
    //IMG É UMA IMAGEVIEW . . .
    img.setImageBitmap(bm_3);
}

Based on the above algorithm, I have tried to implement it recursively. However, it shows error of java.lang.StackOverflowError: stack size 1038KB


Using recursion (java.lang.Stackoverflowerror)

RECURSION

private Bitmap grey_scale(int x, int y, Bitmap bm_3) {
        //IF PARA PERCORRER TODO Y . . .
        if (y < bm_3.getHeight()) {
            String hex = Integer.toHexString(bm_3.getPixel(x, y));
            if (hex.length() == 8) {
                String hexX = "#" + convert_Hex_to_grey("" + hex.charAt(0) + hex.charAt(1),
                                                        "" + hex.charAt(2) + hex.charAt(3),
                                                        "" + hex.charAt(4) + hex.charAt(5),
                                                        "" + hex.charAt(6) + hex.charAt(7));


                bm_3.setPixel(x, y, Color.parseColor(hexX));
            }
            //O ERRO OCORRE NESTE RETURN ! ! !
            return grey_scale(x, y+1, bm_3);

        }
        //IF PARA PERCORRER TODO X, ZERANDO Y A CADA TROCA DE X.
        if (x < bm_3.getWidth()) {
            return grey_scale(x+1, 0, bm_3);
        }
    //RETORNA BITMAP
    return bm_3;
}

BUTTON ON CLICK CALLING RECURSION

public void go(View v){

    bm_3 = bm_3.copy(Bitmap.Config.ARGB_8888, true);
    //FAZ RECURSAO DENTRO DE UMA THREAD . . .
    new Thread(new Runnable() {
        @Override
        public void run() {
            //CHAMA A RECURSAO
            bm_3 = grey_scale(0, 0, bm_3);

            //VOLTA PRA THREAD PRINCIPAL PARA ATUALIZAR O IMAGEVIEW . . .
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    img.setImageBitmap(bm_3);
                }
            });
        }
    }).start();
}
  • 1

    What size of the image?

  • The image size is 5,577 bytes, giving 788 by 788 pixels

  • 1

    The approximate depth is 621,000 recursive calls. You must not have set the stack size for this. I believe that only fix the size of the stack not adjusted for larger cases.

  • How do you set her size?

  • 1

    Each call adds by 12 bytes on the argument-only stack, not counting the extra function call structure information. Most calls also add at least 4 bytes of reference to the local variable hex. Maybe the compiler is smart enough to drop the reference to hex before making the recursive call.

  • -Xms i think. But you need to get an idea of how much you’re going to consume, or test until you don’t overflow stack

  • 1

    -Xss is the size of the stack, -Xmx is the initial heap size; more details here: https://stackoverflow.com/q/3700459/4438007

  • tried this = Thread(Threadgroup group, Runnable target, String name, long stackSize) . But even putting 80m, it ta error.

  • tried with a smaller image, 252x252 and gave the same error

  • 1

    It is running through the eclipse, command line, another ide or as?

  • By Android Studio

  • From what I’ve seen, the JRE is free to define the size of the stack, taking as reference a suggestion of what is passed as argument. I also don’t know what the relationship between the secondary thread stack and the main one is. I also don’t know if it’s platform dependent

  • in this case, I think that trying to use the arguments of the Java virtual machine will not help.

  • 1

    Ever tried with a 1 pixel high image? Just to make sure it’s not an algorithm error?

  • I did something similar this when I was testing with the big printava image at each line change, it hangs on line 2. But it gets to start her. In the smaller image, it hangs on line 55 (with Thread) with limit of 80m

  • tries a smaller and more controlled image. That’s why the 1 pixel

  • Can it be indirect recursion? Put it on a stack and process the result? The advantage of this is that the pressure stays on the dynamic part of the memory

Show 12 more comments

1 answer

3


The problem here is the recursion size. Its recursion is approximately 621,000 calls, given the 788 x 788 image.

Each recursive call at least inserts the call arguments into the stack. In this case, there are two integers and a reference; the integers are 4 bytes each, the reference is 8 or 4 bytes (8 bytes for 64 bits and 4 bytes for 32 bits). So you put at least 12 bytes for each recursive call. Thus, not considering other factors, the minimum required for the stack is 10 or 12 megabytes of only recursive call arguments. Who knows how much more of other information?

Anyway, maybe with 64 megabytes of stack? To determine this value, the virtual machine argument -Xss 64M defines that. Source

Well, AP is having the problem running on Android Studio, so try to do these tweaks with the JVM may not result in anything.


PS: Just before I finished writing this answer, I saw that setting the size of the stack in the thread did not work. I’ll inspect a little longer and then edit the answer with whatever I find

Browser other questions tagged

You are not signed in. Login or sign up in order to post.