утечка памяти в c # неуправляемые ресурсы - PullRequest
0 голосов
/ 28 апреля 2018

Привет всем, кого я знаю, что этот вопрос задавался много раз, и я сам гуглил его перед тем, как спросить, но я просто не могу понять это.

Я только начал изучать C # через наполовину созданное приложение кем-то другим и столкнулся с этой проблемой утечки памяти. Я запустил профилировщик памяти .NET (программное обеспечение от red-gate) и сузил его до определенного блока кода в приложении.

Это небольшая 2D-игра, каждый монстр живет на карте, которая представляет собой список тайлов. Каждый монстр «Думай ()» каждую секунду, куда двигаться дальше.

Подумайте (), чтобы получить путь (Список плиток) к цели.

Вот 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 голосов
/ 28 апреля 2018

Может кто-нибудь подсказать, как можно улучшить производительность памяти на это? * * 1002

Общая структура данных может использовать много памяти для большой карты, поскольку каждая плитка содержит свой собственный список соседей.

CopyTiles делает полную копию всего этого. Реализация в порядке. (Может быть и лучше, но это не ужасно неэффективно).

Я подозреваю, что ваш код (где-то не показанный в вопросе), вероятно, часто вызывает CopyTiles, и это причина, по которой у вас уходит память. Поместите туда точку останова или счетчик и посмотрите, как часто она вызывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...