java.lang.StackOverflowError: stack size 1038KB

0

I'm doing an algorithm that converts a leaving it in shades of gray.

I was able to do it using for but I would like to do it recursively.

Using for (This is working fine)

//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 algorithm above, I tried to implement it recursively. However, it has an error of java.lang.StackOverflowError: stack size 1038KB

Using recursion (java.lang.StackOverflowError)

RESOURCES

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 THAT CALLS FOR RESOURCE

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();
}
    
asked by anonymous 14.09.2017 / 00:53

1 answer

3

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

Each recursive call at least inserts the call arguments into the stack. In case, two integers are 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). Therefore, a minimum of 12 bytes is set for each recursive call. So, not considering other factors, the minimum required for the stack is only 10 or 12 megabytes of recursive call arguments. Who knows how much more information?

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

  

Well, AP has the problem running in Android Studio, so trying to do those tweaks with the JVM may not work.

PS: shortly before writing this answer, I saw that setting the stack size on the thread did not work. I'm going to inspect a little more and then edit the answer with whatever I find

    
14.09.2017 / 01:45