Где хранится буфер объектов List <MyClass>? Это на RAM или HDD?
Мой вопрос может показаться немного расплывчатым. Но я хочу знать, где хранится буфер List<>
.
У меня есть список List<MyClass>
, к которому я добавляю элементы из бесконечного цикла. Но потребление ОЗУ службы Windows (внутри которой я создаю Список) никогда не превышает 17 МБ. На самом деле он колеблется между 15-16 МБ, даже если я продолжаю добавлять элементы в список.
Я пытался выполнить нагрузочное тестирование моего сервиса и наткнулся на это.
Может ли кто-нибудь сказать мне, удаляет ли данные данные в какое-то временное место на машине, и выбирает это оттуда, поскольку я не вижу увеличения потребления ОЗУ.
Метод, который я вызываю бесконечно, это AddMessageToList().
class MainClass
{
List<MessageDetails> messageList = new List<MessageDetails>();
private void AddMessageToList()
{
SendMessage(ApplicationName,Address, Message);
MessageDetails obj= new MessageDetails();
obj.ApplicationName= ApplicationName;
obj.Address= Address;
obj.Message= Message;
lock(messageList)
{
messageList.Add(obj);
}
}
}
class MessageDetails
{
public string Message
{
get;
set;
}
public string ApplicationName
{
get;
set;
}
public string Address
{
get;
set;
}
}
Ответы
Ответ 1
Ответ на ваш вопрос: "В памяти".
Это может означать оперативную память, и это также может означать жесткий диск (виртуальная память). Диспетчер памяти ОС решает, когда на страницу памяти на виртуальную память, что в основном связано с тем, как часто обращается к памяти (хотя я не претендую на то, чтобы знать специфический для Microsoft алгоритм).
Вы также спросили, почему использование вашей памяти не растет. Во-первых, MegaByte - ОГРОМНЫЙ объем памяти. Если ваш класс достаточно велик, вам потребуется много из них, чтобы отобразить MB. В конечном счете, использование вашей памяти должно увеличиться.
Ответ 2
В общем, объекты С# создаются из кучи, которая находится в памяти. Если вы хотите хранить вещи на диске, есть способы сделать это, но стандартный List<T>
будет жить в памяти.
При создании объекта он будет занимать определенное количество байтов в памяти плюс размер указателей, используемых для ссылки на него. Добавление его в список добавляет только указатель на объект, который вы уже создали, поэтому, если вы добавляете в список много экземпляров одного и того же экземпляра, он не будет расти так быстро, как вы ожидаете.
Если вы действительно хотите проверить влияние больших структур данных на свою память, вам придется наращивать числа. Несколько тысяч средних объектов не собираются занимать много памяти, но несколько миллионов могут.
Вы также можете быть заинтересованы в методе GC.GetTotalMemory()
и его друзьях.
Ответ 3
Обратите внимание, что почти вся память в Windows (и .NET) - это виртуальная память - ее "реальное, физическое" местоположение произвольное, управление памятью Windows обрабатывает это. Однако, независимо от того, использует ли он в настоящее время физическое ОЗУ или файл страницы на жестком диске, он будет отображаться как конфиденциальная память.
Итак, до того, как вы на самом деле создаете элементы и добавляете их в List<T>
. Сколько объектов есть? Вы добавляете один и тот же объект снова и снова или каждый раз создаете новый? Вы используете один и тот же экземпляр List или создаете другие? Поддерживаете ли вы ссылки на созданные объекты (и экземпляры списка), или вы отбрасываете их? Вы действительно что-то делаете с объектом/списком? Если нет, оптимизатор мог бы удалить код alltogether (он очень консервативен, хотя я бы не стал рассчитывать на то, что при добавлении элементов в список - это очень сложный сценарий с возможными побочными эффектами).
В идеальном случае с наименьшей памятью вы можете использовать около четырех байтов в элементе списка, что не так много - вам понадобится 262 144 элемента, чтобы потреблять один мегабайт памяти!
Покажите нам свой код, весь цикл и его окружение. Затем мы можем сказать вам, что вы на самом деле делаете.
EDIT: это в службе WCF? Вы должны были сказать это раньше. Где вы храните класс MainClass
? Если он находится внутри класса службы WCF, он может длиться не более одного запроса. И даже если вы исправите это и сохраните его в чем-то более постоянном, например, в статическом классе, вы столкнетесь с сложностями, когда все будет собрано, как перезагружается служба и т.д. Если вам нужны безопасные данные для более длительного, чем один запрос, сохранение его в памяти процесса недостаточно. Если вам все равно, что данные могут быть выбрасыты раз в то время, вы можете сделать экземпляр List
статическим (он не будет использоваться совместно или не будет сохранен иначе). В противном случае используйте базу данных.
Ответ 4
Спекулируя из вашего редкого описания, есть два вида вещей, которые вы не понимаете:
-
Использование 15-16 МБ, которое вы видите, может не иметь никакого отношения к размеру вашего списка: это могут быть требования к памяти для остальной части программы, и ваш список потребляет лишь незначительный объем памяти в сравнение. Даже если вы явно не создаете объекты, вашей программе по-прежнему приходится загружать библиотеки и прочее, что занимает память.
-
Я не знаю С#, поэтому я не знаю, относится ли это к List
, но одна из стандартных реализаций контейнерного класса для динамического выделения массива для хранения объектов... и если массив всегда заполняется, тогда вы выделяете новый массив в два раза больше размера и копируете все в новый массив и продолжаете двигаться (фактическое отношение может быть чем-то иным, чем $2 $). Это может повлиять на то, что ваше использование памяти остается постоянным в течение длительного времени, пока вы, наконец, не заполните массив, а затем внезапно вскакивает в размере, чтобы оставаться постоянным снова в течение длительного времени.