Как можно написать unit-тест в Unity для проверки выделения памяти?

Как можно измерить и получить информацию о том, сколько памяти было выделено в процессе выполнения теста для Unity? Например, существует код теста, в котором публикуются события, и хочется измерить количество выделенной памяти в этом процессе.
  • 31 января 2024 г. 17:01
Ответы на вопрос 2
Для профилирования выделения памяти в Unity можно использовать Profiler API или Mono.Profiler. Однако стоит отметить, что полноценное unit-тестирование выделения памяти может быть сложным из-за недетерминированных особенностей сборщика мусора и внешних факторов, влияющих на выделение памяти. Тем не менее, можно попробовать написать тест, который будет ориентировочно оценивать выделение памяти.

Вот примерной шаблон unit-теста, который можно использовать для измерения выделения памяти в Unity:

```csharp
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using Unity.Profiling;

public class MemoryAllocationTest
{
    private ProfilerMarker customTestMarker;

    [SetUp]
    public void SetUp()
    {
        // Инициализация маркера профайлера перед тестами
        customTestMarker = new ProfilerMarker("CustomTestMarker");
    }

    [Test]
    public void CheckMemoryAllocations()
    {
        // Используйте ProfilerRecorder для запуска сбора данных по выделенной памяти
        var recorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC.Alloc");

        customTestMarker.Begin();

        // Тестируемый код
        // Пример: EventPublisher.PublishEvent();

        customTestMarker.End();

        // Остановите сбор данных и получение результатов
        recorder.Stop();

        // Получаем количество выделенной памяти в байтах
        var memoryAllocations = recorder.sampleBlockCount;
        Debug.Log($"Memory allocated: {memoryAllocations} bytes");

        // Ожидаем, что выделенная память будет ниже некоторого порогового значения
        Assert.LessOrEqual(memoryAllocations, expectedAllocationLimit, "Too much memory allocated during the test.");

        recorder.Dispose();
    }
}
```
В этом примере мы используем `ProfilerRecorder` для отслеживания количества выделений памяти, которые происходят внутри определённого блока кода, помеченного `customTestMarker`.

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

Для более точного анализа и обнаружения точных утечек памяти или неоптимального выделения памяти рекомендуется использовать инструменты профилирования, например Unity Profiler, который предоставляет более широкие возможности для анализа производительности приложения в реальном времени.
1. Для тестирования выделения памяти нужно использовать dotMemory. У него есть отдельный плагин для всяких unit фреймвоков - https://blog.jetbrains.com/dotnet/2018/10/04/unit-... 
Единственная проблема - она платная, а других аналогов мне не известно.
2. Нашел репозиторий с кодом для профилирования Unity, но последнее обновление 5 лет назад - https://github.com/donaldwuid/unitymemoryprofilert...
3. У самого Unity есть документация по профилированию памяти, но это не для юнит тестов, а для всего приложения - https://unity.com/how-to/analyze-memory-usage-memo...

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