Размер экземпляров класса
От: -Cheese-  
Дата: 16.09.10 06:52
Оценка:
Всем привет.
Есть следующая проблемка.
Присутствует достаточно крупное приложение. В последнее время повилась проблема с OutOfMemoryException. Есть подозрение, что один из используемых классов хранит у себя коллекцию чего-то, которую он не подчищает. Классов достаточно много и исходники не всех классов присутствуют.
Баг проявляется только при больших нагрузках на приложение, которые смоделировать не представляется возможным по многим причинам.

Нужно написать какой-нибудь анализатор загруженных в домен библиотек и созданных экземпляров классов на предмет занимаемой ими памяти, чтоб сузить круг поиска бага. Куда смотреть?
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re: Размер экземпляров класса
От: _FRED_ Черногория
Дата: 16.09.10 07:03
Оценка: +2
Здравствуйте, -Cheese-, Вы писали:

C>Есть следующая проблемка.

C>Присутствует достаточно крупное приложение. В последнее время повилась проблема с OutOfMemoryException. Есть подозрение, что один из используемых классов хранит у себя коллекцию чего-то, которую он не подчищает. Классов достаточно много и исходники не всех классов присутствуют.
C>Баг проявляется только при больших нагрузках на приложение, которые смоделировать не представляется возможным по многим причинам.

C>Нужно написать какой-нибудь анализатор загруженных в домен библиотек и созданных экземпляров классов на предмет занимаемой ими памяти, чтоб сузить круг поиска бага. Куда смотреть?


Таких анализаторов уже понаписано до вас Вам нужен какой-либо .NET Memory Profiler.
Help will always be given at Hogwarts to those who ask for it.
Re: Размер экземпляров класса
От: RadmirT Россия  
Дата: 16.09.10 07:03
Оценка:
Есть замечательный инструмет JetBrains dotTrace.

Здравствуйте, -Cheese-, Вы писали:

C>Всем привет.

C>Есть следующая проблемка.
C>Присутствует достаточно крупное приложение. В последнее время повилась проблема с OutOfMemoryException. Есть подозрение, что один из используемых классов хранит у себя коллекцию чего-то, которую он не подчищает. Классов достаточно много и исходники не всех классов присутствуют.
C>Баг проявляется только при больших нагрузках на приложение, которые смоделировать не представляется возможным по многим причинам.

C>Нужно написать какой-нибудь анализатор загруженных в домен библиотек и созданных экземпляров классов на предмет занимаемой ими памяти, чтоб сузить круг поиска бага. Куда смотреть?
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
Re[2]: Размер экземпляров класса
От: -Cheese-  
Дата: 16.09.10 08:12
Оценка:
Здравствуйте, _FRED_, Вы писали:
_FR>Таких анализаторов уже понаписано до вас Вам нужен какой-либо .NET Memory Profiler.

это всё понятно, но в режиме отладки смоделировать ситуацию не получается
мне не нужен реал-тайм
я хотел бы в приложение встроить этот анализатор. который каждые минут 5 сохранял статистику и самое главное, чтобы он не мешал приложению работать
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Re[3]: Размер экземпляров класса
От: Sinix  
Дата: 16.09.10 08:21
Оценка:
Здравствуйте, -Cheese-, Вы писали:


C>это всё понятно, но в режиме отладки смоделировать ситуацию не получается

C>мне не нужен реал-тайм
Можно сохранять dump-файлы и дебажить по ним
http://msdn.microsoft.com/en-us/library/d5zhxt22(v=VS.90).aspx
http://blogs.msdn.com/b/carloc/archive/2007/10/08/ok-now-how-do-i-capture-my-dump.aspx
http://stackoverflow.com/questions/27742/finding-the-crash-dump-files-for-a-c-app
Re: Размер экземпляров класса
От: Nikolay_P_I  
Дата: 16.09.10 09:10
Оценка:
C>Присутствует достаточно крупное приложение. В последнее время повилась проблема с OutOfMemoryException. Есть подозрение, что один из используемых классов хранит у себя коллекцию чего-то, которую он не подчищает. Классов достаточно много и исходники не всех классов присутствуют.
C>Баг проявляется только при больших нагрузках на приложение, которые смоделировать не представляется возможным по многим причинам.

C>Нужно написать какой-нибудь анализатор загруженных в домен библиотек и созданных экземпляров классов на предмет занимаемой ими памяти, чтоб сузить круг поиска бага. Куда смотреть?


Для начала — просто писать в лог любого типа размер сжираемой памяти. Если вылет происходит не при приближении к лимиту оперативки на приложение и свопа на диске — стоит поискать в выделении больших массивов и утыкать программу GC.Collect(). Сейчас, правда, возможно, поправили, а в Framework 1.1 частое выделение и удаление больших (примерно 100МБ) массивов приводило к OutOfMemory при том, что памяти приложение сожрало даже меньше 1 ГБ. Чисто внутренний баг .NET
Re[2]: Размер экземпляров класса
От: Aen Sidhe Россия Просто блог
Дата: 16.09.10 09:11
Оценка:
Здравствуйте, RadmirT, Вы писали:

RT>Есть замечательный инструмет JetBrains dotTrace.


Он не умеет аттачиться к уже работаещему процессу.
С уважением, Анатолий Попов.
ICQ: 995-908
Re: Размер экземпляров класса
От: vecs Россия  
Дата: 17.09.10 05:29
Оценка:
Попробуйте вызывать
GC.Collect();
после каждой операции с большими коллекциями/массивами объектов.
Это освободит память, занятую объектами, которые уже не используются.
Иначе CLR будет освобождать память не тогда, когда Вам надо, а когда ему заблагорассудится.
Re[2]: Размер экземпляров класса
От: _FRED_ Черногория
Дата: 17.09.10 06:19
Оценка:
Здравствуйте, vecs, Вы писали:

V>Попробуйте вызывать

V>GC.Collect();
V>после каждой операции с большими коллекциями/массивами объектов.
V>Это освободит память, занятую объектами, которые уже не используются.
V>Иначе CLR будет освобождать память не тогда, когда Вам надо, а когда ему заблагорассудится.

В том числе и тогда, когда память потребуется приложению.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Размер экземпляров класса
От: vecs Россия  
Дата: 17.09.10 07:52
Оценка:
V>>Иначе CLR будет освобождать память не тогда, когда Вам надо, а когда ему заблагорассудится.
_FR>В том числе и тогда, когда память потребуется приложению.

Теоретически, да. И только при условии, что новая память запрашивается непосредственно из managed-кода (нет никаких COM Interop вызовов, процедур в Win32 Dll-ках, не используются сокеты и т.п.).

А еще, вроде бы есть ограничения по объему используемой памяти для .Net приложения. Чуть ли не более 800 — 1000 мегабайт (если Windows не х64). К тому же поговаривают о "прожорливости" некоторых классов типа List<> и Dataset.
Еще видел где-то, что в .Net 2.0 был такой баг (неожиданный OutOfMemoryException) и к нему была выпущена заплатка.

Что касается исходного вопроса по отладке — неужели в отладочном режиме нельзя понять, какие объекты едят память? Даже при минимальной нагрузке должно быть видно.
Re[4]: Размер экземпляров класса
От: _FRED_ Черногория
Дата: 17.09.10 08:06
Оценка:
Здравствуйте, vecs, Вы писали:

V>>>Иначе CLR будет освобождать память не тогда, когда Вам надо, а когда ему заблагорассудится.

_FR>>В том числе и тогда, когда память потребуется приложению.

V>Теоретически, да. И только при условии, что новая память запрашивается непосредственно из managed-кода (нет никаких COM Interop вызовов, процедур в Win32 Dll-ках, не используются сокеты и т.п.).


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

V>А еще, вроде бы есть ограничения по объему используемой памяти для .Net приложения. Чуть ли не более 800 — 1000 мегабайт (если Windows не х64). К тому же поговаривают о "прожорливости" некоторых классов типа List<> и Dataset.

V>Еще видел где-то, что в .Net 2.0 был такой баг (неожиданный OutOfMemoryException) и к нему была выпущена заплатка.

Про Лохнесское Чудовище тоже поговаривают, а оно не виновато.

V>Что касается исходного вопроса по отладке — неужели в отладочном режиме нельзя понять, какие объекты едят память?


А почему должно быть можно "в отладочном режиме" и не должно без него? Управляемые объекты на то и _управляемые_, что среде известно, что за объект занял память.

V>Даже при минимальной нагрузке должно быть видно.


Не вижу, как величина нагрузки может влиять на видимость того, "какие объекты едят память"
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Размер экземпляров класса
От: Aviator  
Дата: 17.09.10 08:11
Оценка:
Здравствуйте, RadmirT, Вы писали:

RT>Есть замечательный инструмет JetBrains dotTrace.

Прям такой уж замечательный... От Red Gate покруче будет.
Re[3]: Размер экземпляров класса
От: Aen Sidhe Россия Просто блог
Дата: 17.09.10 08:17
Оценка:
Здравствуйте, Aviator, Вы писали:

A>Здравствуйте, RadmirT, Вы писали:


RT>>Есть замечательный инструмет JetBrains dotTrace.

A>Прям такой уж замечательный... От Red Gate покруче будет.

Что может аттачиться к уже работающим процессам? Или анализировать дампы по 16-20 гигабайт?
С уважением, Анатолий Попов.
ICQ: 995-908
Re[4]: Размер экземпляров класса
От: Aen Sidhe Россия Просто блог
Дата: 17.09.10 08:19
Оценка:
Здравствуйте, vecs, Вы писали:

V>>>Иначе CLR будет освобождать память не тогда, когда Вам надо, а когда ему заблагорассудится.

_FR>>В том числе и тогда, когда память потребуется приложению.

V>Теоретически, да. И только при условии, что новая память запрашивается непосредственно из managed-кода (нет никаких COM Interop вызовов, процедур в Win32 Dll-ках, не используются сокеты и т.п.).


V>А еще, вроде бы есть ограничения по объему используемой памяти для .Net приложения. Чуть ли не более 800 — 1000 мегабайт (если Windows не х64). К тому же поговаривают о "прожорливости" некоторых классов типа List<> и Dataset.


У List<T> оверхед над T[] ровно в 1 int, насколько я помню.

V>Еще видел где-то, что в .Net 2.0 был такой баг (неожиданный OutOfMemoryException) и к нему была выпущена заплатка.


OutOfMemoryException не означает, что нет свободной памяти. Оно означает, что нет куска нужного размера.

V>Что касается исходного вопроса по отладке — неужели в отладочном режиме нельзя понять, какие объекты едят память? Даже при минимальной нагрузке должно быть видно.


Не всегда.
С уважением, Анатолий Попов.
ICQ: 995-908
Re[5]: Размер экземпляров класса
От: vecs Россия  
Дата: 17.09.10 09:30
Оценка:
AS>У List<T> оверхед над T[] ровно в 1 int, насколько я помню.

Тут заковыка в том, что память под элементы List<T> выделяется динамически.
Это значит, что при добавлении в список нового элемента (ссылки), под который не хватает выделенной ранее памяти, динамически выделяется память под новые элементы, причем размером в два раза больше, чем текущая емкость списка.
Т.е., например, если в списке 262140 элементов, то при добавлении 262141-го элемента CLR попытается выделить память еще под 262140 элементов, т.е. выделенная в памяти емкость списка сразу станет 524280! А ведь каждый элемент списка — это 4 или 8 байт (в зависимости от разрядности ОС). Вот тут-то нас и может поджидать OutOfMemoryException.

Вот неплохая статья на тему: О побочных эффектах неявного выделения памяти в .Net.
Там, кстати, есть фраза, напрямую относящаяся к описанной в вопросе программе:
"For bulk in-memory data storage, swarms of small objects can push the cost up to unacceptable levels, especially on 64 bit systems."
То бишь: "Одновременное хранение в памяти большой массы мелких объектов может задрать уровень потребления памяти до немыслимого уровня, особенно в 64-разрядной ОС."
Re[6]: Размер экземпляров класса
От: QrystaL Украина  
Дата: 17.09.10 10:00
Оценка:
Здравствуйте, vecs, Вы писали:
V>например, если в списке 262140 элементов, то при добавлении 262141-го элемента CLR попытается выделить память еще под 262140 элементов, т.е. выделенная в памяти емкость списка сразу станет 524280! А ведь каждый элемент списка — это 4 или 8 байт (в зависимости от разрядности ОС). Вот тут-то нас и может поджидать OutOfMemoryException.

Для таких случаев существует свойство Capacity.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.