Поскольку структура сущностей хранит данные в памяти (как и многие ORM), то, как и во многих коллекциях в памяти, вероятно, существуют внутренние массивы. При добавлении элементов в коллекцию внутренний массив увеличивается в два раза.
Например, если у вас есть коллекция, такая как ArrayList, содержащая 256 элементов, и вы добавляете в нее 257-й элемент, то внутри происходит выделение нового блока памяти для массива из 512 элементов, а массив из 256 элементов копируется в новый массив из 512 элементов, а затем массив из 256 элементов становится доступным для сборки мусора. Таким образом, в момент перехода у вас будет 768 предметов, выделенных в памяти только потому, что вы добавили 257-й предмет. Я столкнулся с этой головной болью при использовании потока памяти, потому что вам нужно почти в 3 раза больше нерасфрагментированной памяти, чем то, что вам действительно нужно. Это свойство .Capacity, которое вы видите в коллекциях, и оно почти всегда имеет степень 2 (поскольку при необходимости оно удваивается).
Могу поспорить, что есть внутренние массивы, которые удваиваются в размере, необходимом для поддержки ваших коллекций объектов в памяти. Таким образом, 300 000 объектов одного типа, вероятно, будут храниться во внутреннем массиве размером 524 288. Кроме того, если это похоже на аналогичные методы где-либо еще в .NEt Framework, то всякий раз, когда добавлялся 262145-й элемент, в памяти существовал как массив 262144, так и 524288, в то время как элементы копировались в новый массив. Всего в памяти 786432 предметов. Старый массив будет зависать, пока сборщик мусора не решит, что он больше не нужен.
В платформе Entity могут быть некоторые параметры, касающиеся поддержки параллелизма, которые можно отключить, что может улучшить использование памяти. Я здесь только размышляю, но для поддержки параллелизма они хранят в памяти как текущую версию данных, так и оригинальную версию для сравнения для поддержки параллелизма.
Я бы также посмотрел на фильтрацию данных, с которыми вы взаимодействуете. Попробуйте найти умные критерии для ограничения того, что запрашивается и загружается в память. Например, если у вас было приложение, которое позволяло пользователю редактировать учетные записи клиентов, но им были назначены только определенные учетные записи, используйте это в качестве критерия фильтрации, чтобы загружать в память только те учетные записи, с которыми пользователь мог потенциально взаимодействовать.