GC собирать ... что? - PullRequest
       24

GC собирать ... что?

3 голосов
/ 23 декабря 2009

Я пытаюсь оптимизировать мой движок (C # + SlimDX), чтобы сделать как можно меньше выделений (чтобы не запускать GC слишком часто), используя в качестве руководства профилировщик, который дает мне, где генерируется объект с мусором. Это идет довольно хорошо (снижение с примерно 20 МБ на каждые 5 с до 8 МБ на каждые 1 минуту и ​​половину (да, это был очень мало оптимизированный XD)) Есть метод, при котором я не могу найти ничего объявленного, и я не знаю, что делать. Похоже, что этот метод генерирует 2 облачных объекта за выполнение в своем теле (не в вызываемой функции):

Может кто-нибудь подсказать мне, почему эта функция генерирует объект, который нужно надеть? Я действительно понятия не имею.

    public override void Update()
    {
        base.Update();
        if (LastCheckInstancesNumber != Instances.Count)
        {
            LastCheckInstancesNumber = Instances.Count;
            _needToRegenerateUpdate = true;
        }
        // Crea byte array da usare nel prossimo draw.
        if (_needToRegenerateUpdate)
        {
            Int32 PrimitivesCount = Instances.Count;
            Int32 Size = PrimitivesCount * 80;

            if ((ByteUpdateTemp != null) && (ByteUpdateTemp.Length < Size))
                ByteUpdateTemp = new byte[Size];
            int offset = 0;

            PrimitivesCount = 0;
            Int32 Count = Instances.Count;
            for (int i = 0; i < Count; i++)
            {
                InstancedBase3DObjectInstanceValues ib = Instances[i];
                if (ib.Process)
                {
                    MathHelper.CopyMatrix(ref ib._matrix, ref MatrixTemp);
                    MathHelper.CopyVector(ref ib._diffuseColor, ref ColorTemp);

                    ObjectUpdateTemp[0] = MatrixTemp.M11;
                    ObjectUpdateTemp[1] = MatrixTemp.M12;
                    ObjectUpdateTemp[2] = MatrixTemp.M13;
                    ObjectUpdateTemp[3] = MatrixTemp.M14;
                    ObjectUpdateTemp[4] = MatrixTemp.M21;
                    ObjectUpdateTemp[5] = MatrixTemp.M22;
                    ObjectUpdateTemp[6] = MatrixTemp.M23;
                    ObjectUpdateTemp[7] = MatrixTemp.M24;
                    ObjectUpdateTemp[8] = MatrixTemp.M31;
                    ObjectUpdateTemp[9] = MatrixTemp.M32;
                    ObjectUpdateTemp[10] = MatrixTemp.M33;
                    ObjectUpdateTemp[11] = MatrixTemp.M34;
                    ObjectUpdateTemp[12] = MatrixTemp.M41;
                    ObjectUpdateTemp[13] = MatrixTemp.M42;
                    ObjectUpdateTemp[14] = MatrixTemp.M43;
                    ObjectUpdateTemp[15] = MatrixTemp.M44;
                    ObjectUpdateTemp[16] = ColorTemp.X;
                    ObjectUpdateTemp[17] = ColorTemp.Y;
                    ObjectUpdateTemp[18] = ColorTemp.Z;
                    ObjectUpdateTemp[19] = ColorTemp.W;
                    ByteConverter.WriteSingleArrayToByte(ref ObjectUpdateTemp, ref ByteUpdateTemp, offset);
                    offset += 20;

                    PrimitivesCount++;
                }
            }

            SynchronizedObject so = SynchronizationEventWriter.LockData();
            so.Synchronizedobject = ByteUpdateTemp;
            SynchronizationEventWriter.Update();
            SynchronizationEventWriter.UnlockData();
            _needToRegenerateUpdate = false;

            so = SynchronizationEventWriterNum.LockData();
            so.Synchronizedobject = PrimitivesCount;
            SynchronizationEventWriterNum.Update();
            SynchronizationEventWriterNum.UnlockData();
        }
  }

Примечания:

Новый байт [Размер] НИКОГДА не вызывается из-за кэширования. Функция MathHelper просто копирует каждый элемент (Single) из одного объекта в другой, ничего не создавая. Base.Update () почти ничего не делает (и в любом случае выводится из объекта ALL в моем движке, но только здесь у меня есть объект мусора)

Спасибо !!!

EDIT:

    internal void GetLock()
    {
        Monitor.Enter(InternalLock);
        Value.Locked = true;
        Value.LockOwner = Thread.CurrentThread;
    }
    public SynchronizedObject LockData()
    {
        Parent.GetLock();
        return Parent.Value;
    }

Вот код LockData (). Я не думаю, что это генерирует что-либо: |

Ответы [ 3 ]

2 голосов
/ 23 декабря 2009

Я решил !!!

Проблема была в том, что so.Synchronizedobject = PrimitivesCount; назначал Int32 классу Object. Кажется, что это заменяет каждый раз, когда объект вызывает наложение старого объекта. Я решил использовать класс box, чтобы заключить объект Int32 и просто изменить значение внутри.

1 голос
/ 23 декабря 2009

Что в базе. Обновление (), что-нибудь?

Может ли ваш профилировщик сбросить кучу? Если так, почему я бы поставил точку останова непосредственно перед этим методом и сбросил кучу, а затем снова сразу после нее. Таким образом, вы сможете увидеть, какой тип объекта был создан.

Если не считать того, что грубая сила комментирования построчно - еще одна (ужасная) идея.

Ваши методы MathHelper создают временный объект?

0 голосов
/ 23 декабря 2009

Я просто догадываюсь, но похоже, что вы создаете два объекта SynchronizedObject в девяти нижних строках этой функции:

SynchronizedObject so = SynchronizationEventWriter.LockData();

и

so = SynchronizationEventWriterNum.LockData();

Нет подробных знаний о SynchronizedObject или о том, создает ли LockData () что-либо, но это единственный выбор, который я вижу в вашем коде ...

...