简体   繁体   中英

Is increasing stack size considered to be a bad practice?

I got StackOverflowException in my Java program so I increased stack size using -Xss100m . Does it mean I have problem with my code? I need to solve following task:

  1. You have n clothes
  2. For each pair of clothes x, y you know if x looks ok with y
  3. Put all clothes in max amount of wardrobes but you must be sure that when you get 1 stuff from each wardrobe it will looks ok ( so every stuff must look ok with each other )

I implemented this as a graph in which vertices are clothes and there is an edge between two vertices when they DO NOT look ok with each other. So basically i need to put to one wardrobe every "group" of connected vertices. To do it I use simple DFS:

Part of SimpleGraph class

    Map<Integer, List<Integer>> edges;

    /**
     * Recursive implementation of DFS algorithm adjusted to SimpleGraph class
     * 
     * @param vertice               id of vertice we start at
     * @param visited               array holding info if given vertice was visited or not
     * @param applyToEachVertice    function applied to each vertice we visit
     * @return                      did we marked ANY vertice as visited ( if we DFS starting at
     *                               visited vertice it returns false and true otherwise )
     */
    boolean deepFirstSearch( int vertice, boolean[] visited, Consumer<Integer> applyToEachVertice )
    {
        if(visited[vertice])
           return false;
        visited[vertice] = true;
        applyToEachVertice.accept(vertice);

        // checks if vertice has any neighbours
        if(!edges.containsKey(vertice))
            return true;

        for( int v : edges.get(vertice) )
            if(!visited[v]) 
                deepFirstSearch(v, visited, applyToEachVertice);
        return true;
    }

Main loop

    void resolve( SimpleGraph sg )
    {
        boolean[] visited = new boolean[sg.getVertNumber()];
        final int[] wardrobe = new int[sg.getVertNumber()];        
        for(int i = 0, warNr = 0; i < sg.getVertNumber(); i++)
        {
            final int cNr = warNr;
            if(sg.deepFirstSearch(i, visited, x -> wardrobe[x] = cNr))
                warNr++;
        }
    }

Edit: Actually implementing DFS in iterative way solved the problem. This means I can run my app without changing stack size.

boolean deepFirstSearchNotRecursive( int vertice, boolean[] visited, Consumer<Integer> applyToEachVertice )
{
    if(visited[vertice])
        return false;

    Deque<Integer> stack = new ArrayDeque<>();  
    stack.push(vertice);

    while(!stack.isEmpty())
    {
        Integer next = stack.pop();
        visited[next] = true;
        applyToEachVertice.accept(next);
        if(!edges.containsKey(next))
            continue;
        for(Integer i : edges.get(next))
            if(!visited[i])
                stack.push(i);
    }

    return true;
}

I presume your problems are not caused by infinite recursion as you will be able to spot the problem from StackOverflowException stacktrace and extending the stack size would not help you.

While there are valid reasons to increase a stack trace size, I dare to say the depth of your call chain is proportional to the size of the input passed to your application. In that case, you can never configure it large enough (if you do not constrain the size o the input, which can be a tricky thing for graphs). Switching to algorithm where the depth of the recursion is independent on the input data is the way to go.

Of course, if you have predefined dataset or writing a throw-away script never to be reused, cutting corners is preferable to reimplementing the hearth of the algorithm.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM