Garbage Collector и большие объёмы данных.

Оптимизация кода.

Garbage Collector и большие объёмы данных.

Сообщение Neodrop 24 дек 2009, 09:41

Столкнулся с задачей написать сохранение позиции и вращения 5000 объектов в каждом кадре.
Казалось бы ничего особо сложного, но в процессе работы вылезла принеприятная проблема : начались кошмарные утечки памяти. НА каждые 75 000 записей, я получал объём используемой памяти, приблизительно 3-4 метра.
Писал сперва в List<>. После сохраненения данных на диск, вызывал ему .Clear()
И вот так новость - память не освобождалась и после 10 - 15 циклов я получал переполнение Memory Hip и вылет из приложения.

После штудирования информации о GC, выяснилось, что переменные, к которым система обратилась более одного раза, автоматически маркируются как "долгоживущие" и коллектор перестаёт обращать на них внимание. Всё бы ничего и, может быть, если бы данные были обычными, то не было бы и проблем, но в моём случае, я хранил не Vector3, а собственный класс, ещё и упакованный в dll (не буду объяснять, почему, но иначе невозможно было) и, коллектор оценил их как неуправляемые и начихал на них.
Что я только не перепробовал. Помогло следующее:

Все массивы программы переписал на фиксированные (фтопку generics).
Класс сохраняемых данных унаследовал от IDisposable и переопределил диструктор Disposable()
При удалении экземпляра, обязательный вызов Disposable()
В потоке, пишущем данные на диск, прописал процедуру очищения массива данных (null не очищает) и принудительно вызвал коллектор после каждого очищения.
Код: Выделить всё
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();


По завершении всех этих действия, я смог писать 142 цикла (75000 записей в каждом) не теряя ни метра памяти.

Вывод : GC изумительно работает с малыми объёмами данных и короткоживущими переменными. С долгоживущими, да ещё и толстыми - это просто мрак кромешный. Избегайте их. И следите за памятью в Профайлере. :-B
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Garbage Collector и большие объёмы данных.

Сообщение Tolking 24 дек 2009, 10:07

Ага... Тоже GC напрягает работает там как-то без моего контроля :). Когда начинал, то даже бесило, что ненужно напрямую дистроить объекты. Но пока не сталкивался с траблами.

В твоем случае засада именно с неуправляемыми данными... Если бы они были .нет то проблемы бы невозникло, GC снес бы все объекты на которые нет ссылок (которые не "сохранены" в переменных или в других объектах) т.е. к которым ты ну никак уже несможешь обратиться из кода по технологии .нет. (он и так сносил твою обертку над данными, но данные он сносить немог, ибо фиг его знает, что ты с ними в ДЛЛ можешь делать? Может там свой GC и если он убьет данные програма крашнится?
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Garbage Collector и большие объёмы данных.

Сообщение Neodrop 24 дек 2009, 11:04

Они .NET
Dll с классом сохраняемых данных написана на C#

Вот класс сохраняемых данных (без функций копирую). Мне не кажется, что он очень сложен :

Код: Выделить всё
[System.Serializable]
    public class Data
    {
        private float vx, vy, vz, qx, qy, qz, qw;
    }


Семь обыденных float чисел.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Garbage Collector и большие объёмы данных.

Сообщение Neodrop 24 дек 2009, 11:10

А вот, как он выглядит в работающем варианте. Данные удаляются качественно, если руками вызвать Dispose()

Код: Выделить всё
[System.Serializable]
    public class Data : IDisposable
    {
        private float vx, vy, vz, qx, qy, qz, qw;

        public Data(Vector3 pos, Quaternion rot)
        {
            vx = pos.x;
            vy = pos.y;
            vz = pos.z;

            qx = rot.x;
            qy = rot.y;
            qz = rot.z;
            qw = rot.w;
        }

        public Data(Transform tr)
        {
            ResetData(tr);
        }

        public void Dispose()
        {
        }

        public void ResetData(Transform tr)
        {
            vx = tr.position.x;
            vy = tr.position.y;
            vz = tr.position.z;

            qx = tr.rotation.x;
            qy = tr.rotation.y;
            qz = tr.rotation.z;
            qw = tr.rotation.w;
        }

        protected Vector3 GetPosition()
        {
            return new Vector3(vx, vy, vz);
        }

        protected Quaternion GetRotation()
        {
            return new Quaternion(qx, qy, qz, qw);
        }

        public void SetPosition(Transform tr)
        {
            tr.position = GetPosition();
            tr.rotation = GetRotation();
        }
    }
}
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Garbage Collector и большие объёмы данных.

Сообщение Tolking 24 дек 2009, 11:13

Нифига себе! А с чего, тогда, ты взял что GC посчитал данные неуправляемыми?

Интиресно, Юнититим GC непереопределяли?
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Garbage Collector и большие объёмы данных.

Сообщение Neodrop 24 дек 2009, 11:15

А вот чёрт его знает. Вряд ли. Почти уверен, что нет.
Для своих классов, может что-то своё добавили, но в целом - на 100% используется Mono GC
Заметьте, что Dispose пустой и всё работает чики-чики. Но, только если вызвать его руками.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Garbage Collector и большие объёмы данных.

Сообщение Tolking 24 дек 2009, 11:24

А Data - то не в моно наверное? Может из-за этого? ИХМО надо забагрепортить эту штуку.
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2715
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Garbage Collector и большие объёмы данных.

Сообщение Neodrop 24 дек 2009, 11:26

Чего не в MONO ? Data это просто название класса. В виду того, что он живёт в моём namespace, я могу задавать ему любое имя, не боясь перехлёстов.
Имя тут точно ни при чём.
А репортить.. Это надо демку писать, а мне недосуг.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Garbage Collector и большие объёмы данных.

Сообщение Fox Rex 27 сен 2010, 13:52

Хотя тема старая. Все таки вставлю свои 3 копейки. GC начинает работать только при переполнении кучи, что значит он может начинать свою работу в самые неудобные моменты, что может плохо сказаться на производительности. Поэтому в самые удобные моменты необходимо вызывать принудительную сборку мусора. Если это делать при удалении ссылки на объект, то лучше это делать в аналоге деструктора, в .NET если мне не изменяет память он называется финализатором. В нем так же удобно освобождать другие занятые ресурсы.
Never more!
Аватара пользователя
Fox Rex
UNITрон
 
Сообщения: 218
Зарегистрирован: 04 сен 2010, 11:24

Re: Garbage Collector и большие объёмы данных.

Сообщение Neodrop 27 сен 2010, 15:04

Это настоятельно нерекомендовано UT. Тем более, что объекты [unity 3D] Unity удаляются собственным сборщиком.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: Garbage Collector и большие объёмы данных.

Сообщение Fox Rex 27 сен 2010, 16:53

Вот и хорошо, одной заботой меньше.
Never more!
Аватара пользователя
Fox Rex
UNITрон
 
Сообщения: 218
Зарегистрирован: 04 сен 2010, 11:24


Вернуться в Код

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1