简体   繁体   English

Unity OutOfMemoryException List.Add()

[英]Unity OutOfMemoryException List.Add()

I am implementing A* search algorithm for my FPS in Unity3D (Version 4.6.1). 我正在Unity3D(版本4.6.1)中为我的FPS实现A *搜索算法。 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. 目前,我在游戏开始时生成了一定数量的敌人预制件,并附有Pathfinder.cs脚本。 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. 在我的Pathfinder类中,每隔1秒(如果我的目标更改了节点),它将调用AStar.cs中的 FindPath()来查找从其自身到目标的新路径。 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. 问题是当我的播放器到处走动一段时间(有时需要几步,有时甚至更长)时,游戏突然冻结,并且任务管理器中的Unity.exe进程拍摄到大约2GB以上的内存(从〜230MB),并且确实如果我停下了现场,就不要下去。 Sometimes Unity unfreezes for a second to Log this error in the console: 有时Unity冻结一秒钟,以在控制台中记录此错误:

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) : 错误指向list.Add(node)上的 AStar.cs脚本:

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. 我最初有ArrayList,但是它出现了相同的错误。

Important: 重要:

This error does not happen when there is only 1 enemy. 只有1个敌人时不会发生此错误。 The error only occurs when there are more than 1 enemies path-finding in the scene. 仅当场景中有1个以上的敌人进行寻路时,才会发生此错误。 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. 我以为这是因为AStar类以及打开和关闭列表都是静态的,所以我尝试将其更改为在非静态上下文中使用,但是仍然发生错误。

I have pasted my AStar, Pathfinder, and Node classes to pastebin: http://pastebin.com/4pQU9Pwc 我已经将AStar,Pathfinder和Node类粘贴到pastebin: http ://pastebin.com/4pQU9Pwc

Any help is greatly appreciated! 任何帮助是极大的赞赏! Thanks. 谢谢。

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;
        }
    }

Thanks to @Altra Viator for finding the cause of the problem, however the end path still produced odd results. 感谢@Altra Viator查找问题的原因,但是最终路径仍然产生奇怪的结果。 I changed the CalculatePath method to include a start node (enemies current node) and added a simple check: 我将CalculatePath方法更改为包括一个起始节点(当前节点为敌人),并添加了一个简单的检查方法:

if(node == start) {
    break;
}

The method now looks like this: 该方法现在如下所示:

private static List<Node> CalculatePath(Node node, Node start) {
    //Retrace the path back through each of the goal nodes parents (to the start node)
    List<Node> list = new List<Node>();
    while (node != null) {
        if (!list.Contains(node)) {
            list.Add(node);
            if(node == start) {
                break;
            }
            node = node.parent;
        }
        else {
            break;
        }
    }
    list.Reverse();
    return list;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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