Более того, объекты, включая GameObjects, часто не оптимизированы для кэша процессора, и они не являются "cache-friendly". Когда процессор загружает данные из памяти, он не берет только те, которые ему нужны, а захватывает сразу целый участок последовательной памяти. Это сделано потому, что процессор предполагает, что в программе данные будут использоваться последовательно, как, например, данные в массиве. Таким образом, существует большая вероятность, что программа обратится к области памяти, которая уже загружена в кэш (cache hit). Однако, если придется обращаться к данным, которых нет в кэше (cache miss), это приведет к обращению к оперативной памяти, что является значительно более медленной операцией — от 10 до 100 раз медленнее.
Давно не использую Unity, но приписывать всё это конкретно к Unity-проблемам, и делать из GameObjects какое-то зло - неправильно. Вышеперечисленные моменты касаются многих движков - количество объектов и их структурирование важны, пул объектов помогает, хотя и не везде применим, кэширование - хорошая практика, минимизация лишних вызовов в цикле и вобще - хорошая практика, сборщик мусора имеет свои нюансы, и так далее.
В разных движках, естественно, данные проблемы решены несколько иначе, но за это уплачена разная цена - не хочешь использовать GC, тогда вот тебе какие-нибудь плюсы и иди работай с памятью сам. Это не какие-то очередные GameObjects во всём виноваты, а те разработчики, которые специфику используемого движка не учитывают.
Действительно, проблема GameObjects везде одинаковая, не только на Unity. Стандартный GameObject подход очень легок для освоения, поэтому он привлекает разработчиков. Но под всем этим скрывается ООП, которая является очень простой парадигмой для понимания, но очень сложной в реализации.
Один умный человек подметил, что ECS штука хорошая, но когда она работает на низком уровне движка (рендер, физика, звук, сеть, вот это вот все), и разработчик, работающий с движком без особой необходимости с ней не взаимодействует. На уровне игровой логики удобнее как раз компонентный подход, за некоторым исключением.
Да, вы правы, писать некоторые вещи на объектах удобнее. Например, ИИ, так как большинство общепринятых методов использует полиморфизм. Но, может, если бы Ecs был такой же популярный как и GO, мы бы сейчас говорили обратное.
Проблемы с выделением памяти и Garbage Collection
Как по мне, нет здесь никакой проблемы, вопрос того, как вы будете управлять объектами и памятью.
Если сильно захотеть, можно взять контроль в свои руки и вызывать Garbage Collector руками и тогда у вас не будет проблем с тем, что он совпадет с каким-то активным игровым моментом.
Моя идея была в том, что Garbage collector скрывает управление памятью от разработчика и он расслабляется. Конечно можно использовать ручные методы для вызова Garbage Collector в ненагруженные моменты в игре, но тогда это уже будет больше похоже на ручную очистку в стиле C++. Большинство разработчиков не запариваются с этим.
incremental gc не решает? Я забил на всякие NonAlloc версии методов и всё равно никаких заиканий не вижу.