Как я могу узнать, что создает мусор?

Это действительно общий вопрос, основанный на учебе, а не техническая проблема.

Я делаю игру в Unity. Игра включает в себя множество довольно сложных процессов с высокими объектами и, как таковые, я генерирую много мусора. Поскольку все, кто занимается играми, использующими управляемый код, знают, что шипы для сбора мусора являются ОГРОМНЫМ buzzkill. Я также пытаюсь настроить таргетинг на мобильные устройства, поэтому эта боль усиливается.

Моя цель проста: отследить процедуры, которые генерируют большинство мусора и пула, и повторно использовать объекты, чтобы уменьшить нагрузку на сборщик мусора. Я занимаюсь всеми очевидными классами, но мои проблемы с GC сохраняются. Если кто-то может предложить здесь большую мудрость, пожалуйста, принесите его.

То, что я не смог отслеживать в своих исследованиях, - это хороший способ измерить нагрузку GC и выявить проблемы в самом коде. Я могу получить метрики из Unity и классов диагностики о размере пула памяти (хотя я не эксперт в отношении того, что действительно имеет значение для любого из этих чисел), и я могу отобразить общее количество коллекций GC, которые произошли с самого начала, но мои знания об отладке этой проблемы заканчиваются там.

Я знаю, что ДОЛЖНЫ быть более эффективными способами решения этой проблемы. Может ли кто-нибудь указать мне на нужные инструменты или классы инфраструктуры (или библиотеки?), Которые могут помочь мне здесь? Я видел некоторое упоминание о программе отладчика (sgen?), Которая является частью Mono, но я не могу найти загрузку или не говоря уже о том, как подключить ее к игре Unity.

Любая помощь будет принята с благодарностью. Спасибо.

Ответы

Ответ 1

Для С# и Unity3D специально, профилировщик, встроенный в Unity3D, является лучшим инструментом, который вы будете иметь для вас. Вы должны быть очень далеко от Unity Profiler. В частности, Профилировщик CPU:

enter image description here

Я выделил наиболее важный столбец - GC Alloc - который по кадру отображает память, выделенную для сбора мусора. Цель игры состоит в том, чтобы сделать этот столбец максимально приближенным к нулю.

Я предлагаю провести там несколько часов, сыграть в вашу игру, приостановить ее и перекопать в области вашего кода, где GC Alloc показывает номера.

Наконец, я настоятельно рекомендую вам ознакомиться с этим видеоуроком одного из разработчиков Unity по отладке памяти и правильно используя профилировщик Unity Editor.

Ответ 2

Предостережение: все зависит от деталей: общие принципы хороши, но вы правы - реальные данные - это правильная вещь. К сожалению, трудно получить для Unity: я видел отчеты о том, что DotTrace работает для некоторых аспектов игр Unity, но большая часть Unity выглядит как черный ящик для него.

Полезным правилом является поиск операторов new. Это эмпирическое правило, а не 100% научный принцип (структуры создаются с помощью new, но они идут в стек... в основном...), но это хороший ведущий индикатор возможных причин фрагментации, Если вы "что-то новое" и пусть, если просто исчезнете (выйти из сферы действия, разыменоваться и т.д.), Это окажется в сборщике мусора. Кроме того, если вы новичок в партии элементов и разыгрываете некоторые из них, вы также будете фрагментировать кучу, которая делает сбои коллекции хуже, поскольку сборщик пытается дефрагментировать память.

Вот почему большинство рекомендаций в этом пространстве будут использовать пулы, как вы уже делаете.

Вот некоторые ссылки общего назначения, которые могут быть полезны для решения управления памятью в Unity:

http://www.gamasutra.com/blogs/WendelinReich/20131109/203841/C_Memory_Management_for_Unity_Developers_part_1_of_3.php

http://andrewfray.wordpress.com/2013/02/04/reducing-memory-usage-in-unity-c-and-netmono/