c#内存泄漏非托管资源

时间:2018-04-28 07:37:49

标签: c# memory-leaks

大家好我知道这个问题已被多次询问过,我自己也在搜索之前用Google搜索过,但我似乎无法弄明白。

我刚刚开始通过其他人的半建应用程序学习C#并遇到了这个内存泄漏问题。我运行了.NET内存分析器(来自red-gate的软件)并将其缩小到应用程序中的特定代码块。

这是一款基于2D的小型游戏,每个怪物都生活在一张地图中,这是一个Tiles列表。每个怪物“Think()s”每秒都会移动到下一步。

Think()获取目标的walkpath(Tiles列表)。

这是Monster.cs

public class Monster 
{
    NavMesh NavMesh;
    public List<World.Tile> WalkPath;

    public void Think(long tick) {
        LastWalk = ctick;
        var rndMoveTile = Position.CurrentTile.Neighbours[Dice.Random(Position.CurrentTile.Neighbours.Count - 1)];
        WalkPath = FindPath(NavMesh.Tiles[Position.CurrentTile.X,Position.CurrentTile.Y], NavMesh.Tiles[rndMoveTile.X, rndMoveTile.Y]); // <- culprit called here
        DoMove();
    }
}

NavMesh.cs

public class NavMesh
{
    public World.Tile[,] Tiles;
    public NavMesh(World.Map map)
    {
        Tiles = map.CopyTiles; //<- this is causing trouble i think
    }
}

Tile.cs

public class Tile : IAStarNode<Tile>
{
    public int X;
    public int Y;
    public int WalkFlags;
    public Portal Portal;
    public bool Occupied;

    public enum E_WalkFlags
    {
        Walkable = 1,
        Projectile = 2,
        Flyable = 4,
    }

    public List<Tile> Neighbours { get; set; }
    public double Cost { get; set; }
    public Tile ParentNode { get; set; }
    public bool inopenlist { get; set; }
    public bool inclosedlist { get; set; }
    //  public long runindex { get; set; }

    public Tile()
    {
        this.Neighbours = new List<Tile>();
    }

    public Tile(int x, int y, int WalkFlags)
    {
        X = x;
        Y = y;
        this.WalkFlags = WalkFlags;
        this.Neighbours = new List<Tile>();
    }
}

最后是罪魁祸首(我想......)

Map.cs

    public Tile[,] CopyTiles
    {
        get
        {
            var ret = new Tile[sizeX, sizeY];
            for (int xx = 0; xx < sizeX; xx++)
            {
                for (int yy = 0; yy < sizeY; yy++)
                {
                    var oldtile = Tiles[xx, yy];
                    ret[xx, yy] = new Tile(xx, yy, oldtile.WalkFlags, oldtile.Occupied);
                }
            }
            for (int xx1 = 0; xx1 < sizeX; xx1++)
            {
                for (int yy1 = 0; yy1 < sizeY; yy1++)
                {
                    var oldtile = Tiles[xx1, yy1];
                    var newtile = ret[xx1, yy1];
                    for (int x = 0; x < oldtile.Neighbours.Count; x++)
                    {
                        var oldnei = oldtile.Neighbours[x];
                        newtile.Neighbours.Add(ret[oldnei.X, oldnei.Y]);
                    }
                }
            }
        }
    }

我已经读过我必须实现IDisposable来处理我在Tile.cs上做过的非托管资源并试图做using(Tile[,] Tiles = new Tiles[,])但我收到编译错误,说Tile[,]没有IDisposable接口,我不知道[*,*]类型是什么。

有人可以建议我如何提高内存性能吗?

1 个答案:

答案 0 :(得分:1)

  

任何人都可以建议我如何提高内存性能   此?

整个数据结构可能会为大型地图使用大量内存,因为每个磁贴都拥有自己的邻居列表。

CopyTiles正在制作所有这些内容的完整副本。实施没问题。 (它可能会更好,但效率不是很低)。

我怀疑你的代码(问题中没有显示的地方)可能会调用CopyTiles,这就是你的内存爆炸的原因。在那里放一个断点或一个计数器,看看它被调用的次数。