Android: Increase call stack size
Asked Answered
B

3

12

I have an application with very complex UI, containing many layouts nested one in another. While Creating another layout, I've caught a StackOverflowError

Wondering, I've created two test examples:

1) Hello world application with following xml for main Activity

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <FrameLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >

            <!-- ...So on 30 times... -->

                <FrameLayout
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent" >

                </FrameLayout>

            <!-- ...So on 30 times... -->

        </FrameLayout>
    </FrameLayout>
</FrameLayout>

causes StackOverflowError while drawing the layout (cause every layout recursively draws it's children)

2) The following test case

public class TestOverflowActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        overflow(0);
    }

    private void overflow(int i){
        android.util.Log.i("Stack depth:", " = " + i);
        overflow(i+1);
    }
}

causes StackOverflowError on depth about 260-270 calls.

Every call of stack element for second test case takes 4 bytes for return address + 4 bytes for parameter = 8 bytes. It's possible that Dalvik's VM keeps a bit more info in every element, but even 16 bytes per element * 260 calls = about 4Kbytes for maximum overall stack size. This does not seem enough.

Is there any way to increase maximum stack size?

Blaspheme answered 13/1, 2012 at 21:41 Comment(0)
T
26

You might not be able to increase call stack size in the main UI Thread(which is understandable because you're supposed to do as few things as possible here), but you can do it in a separate thread by making use of the Thread object's constructor parameters:

ThreadGroup group = new ThreadGroup("threadGroup");
new Thread(group, runnableObject, "YourThreadName", 2000000).start();

With this example I increased my stack size from 8k (around 260 calls) to 2M (enough for not to get the StackOverFlowException, of course you can add as much as you want as long as the memory can take it), so in the end, for further readers, this is the way you can increase your stack size,although is not recommended, in some cases it's actually necessary for example an algorithm with extensive recursive calls and of course by doing all the hard work in a worker thread(as you're supposed to) with your specified stack size and just "posting" changes in UIs using the main UI Thread with Handlers or whatever mechanism you would like to use to interact with it...

Hope this Helps...

Regards!

Tampa answered 14/11, 2013 at 1:27 Comment(1)
True, and I think this is a good answer, although I don't think it's guaranteed to honor the stack size? probably best to avoid the situation entirely if possible.Upwards
P
0

You definitely don't want to nest layouts inside each other like that. If you find yourself nesting three or four times then the construction of the view becomes less and less efficient, which can cause activity transitions to start and probably in your case finish before the view is created. Which will look weird, or be a complete waste of an activity transition.

You should make your root layout a relative layout and have all your frame layouts as children of that root relative layout.

Piers answered 9/3, 2016 at 11:21 Comment(0)
H
-1

If you need this complex layout (as many will doubt) you can still draw it programticaly in onCreate method.

Hulse answered 14/1, 2012 at 21:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.