Search code examples
c#unity-game-enginepath-findinga-star

Unity OutOfMemoryException List.Add()


I am implementing A* search algorithm for my FPS in Unity3D (Version 4.6.1). At the moment I have a set number of enemy prefabs spawning at the start of the game with a Pathfinder.cs script attached to them. In my Pathfinder class, every 1 second (if my target has changed nodes), it calls FindPath() in AStar.cs which finds the new path from itself to the target. At the moment, the player is the target; so multiple enemies can be finding a path to the same place.

I have got it all working, and the enemies find the path as expected. The problem is when my player walks around for a while (sometimes a few steps, sometimes longer), when suddenly the game freezes and the Unity.exe process in Task Manager shoots up to around 2GB+ of memory (from ~230MB), and does not go down if i stop the scene. Sometimes Unity unfreezes for a second to Log this error in the console:

OutOfMemoryException: Out of memory
System.Array.Resize[Node] (.Node[]& array, Int32 length, Int32 newSize) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1928)
System.Array.Resize[Node] (.Node[]& array, Int32 newSize) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:1912)
System.Collections.Generic.List`1[Node].set_Capacity (Int32 value) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:622)
System.Collections.Generic.List`1[Node].GrowIfNeeded (Int32 newCount) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:100)
System.Collections.Generic.List`1[Node].Add (.Node item) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:91)
AStar.CalculatePath (.Node node) (at Assets/Scripts/AStar.cs:152)
AStar.FindPath (Vector3 startPos, Vector3 endPos) (at Assets/Scripts/AStar.cs:109)
Pathfinder.FindPath () (at Assets/Scripts/Pathfinder.cs:64)
Pathfinder.Update () (at Assets/Scripts/Pathfinder.cs:35)

The error points to my AStar.cs script at list.Add(node):

private static List<Node> CalculatePath(Node node) {
    List<Node> list = new List<Node>();
    while (node != null) {
        list.Add(node); //Error here
        node = node.parent;
    }
    list.Reverse();
    return list;
}

I initially had ArrayList, but it presented the same error.

Important:

This error does not happen when there is only 1 enemy. The error only occurs when there are more than 1 enemies path-finding in the scene. I thought this was because the AStar class and the open and closed lists were static, so i tried changing them to be used in a non-static context, but the error still occurred.

I have pasted my AStar, Pathfinder, and Node classes to pastebin: http://pastebin.com/4pQU9Pwc

Any help is greatly appreciated! Thanks.


Solution

  • It looks like there could be some sort of circular logic where you're adding nodes to a list? Have you tried checking whether or not the list contains a node before you add it?

    while (node != null) {
            if (!list.Contains(node)) {
                list.Add(node);
                node = node.parent;
            }
            else {
                break;
            }
        }