Производительность приложения - возможно, из-за слишком большого выделения в куче больших объектов - PullRequest
2 голосов
/ 13 марта 2020

РЕДАКТИРОВАТЬ: после другого прогона профилирования производительности ясно видно, что на производительность влияют синхронизация потоков и вызовы БД. Спасибо за комментарии, ребята, помогли мне go вернуться в правильном направлении.

Я исследовал приложение, которое, кажется, работает медленно: фактически это рабочий механизм, работающий в IIS / Dot Net 4.0. Работа в основном заключается в вычислении памяти, но процессор не всплывает и выглядит так, как будто система просто зависает между ними, но не видит никаких признаков блокировки в коде приложения и в БД.

Симптомы: Расчеты не слишком сложны, и система с годами замедляется, загрузка ЦП не превышает 7-8% (в основном). Единственное, что я вижу, это то, что память (активный частный рабочий набор) в диспетчере задач поражает действительно большие числа ~ снимает примерно с 500 МБ до 2/3 ГБ, когда я начинаю вычисления.

Я проверил несколько профилировщиков, я вижу, что большая часть памяти фактически не используется точкой net.

Memory Snapshot

Я взял дамп cra sh (cra sh Статистика дампа, не относящегося к pi c выше и был взят отдельно) ) и подтвердил это windbg / sos.

! heapstat -iu

Я не уверен, что мое понимание статистики верно, но похоже, что большая часть памяти в Gen1 / 2 используется незакрученными объектами, но в этом случае я бы ожидал, что эта память будет восстановлена ​​в некоторый момент времени во время сбора G C. Я попытался перезапустить пул приложений, но не увидел влияния на эту неиспользуемую память.

enter image description here Затем я попытался получить статистику о живых и мертвых объектах, используя:

Для живых объектов я нашел следующее:

!dumpheap -stat -live 

Count   TotalSize
611085  231816172

Для мертвых объектов я нашел следующее:

!dumpheap -stat -dead 

Count       TotalSize
19969810    1631716434

Также с точки зрения самого большого вклада (для мертвых объектов) в этот объем памяти я отметил:

Count   TotalSize   Class Name                                              Total Size/Count    
2255867 144375488   System.Data.Listeners`1+Action`4[...                    64
1479    202166952   System.Decimal[]                                        136691.6511
7463    307861416   System.Data.RBTree`1+Node[[System.Int32, mscorlib]][]   41251.69717
9325607 447629136   System.Collections.ArrayList+ArrayListEnumeratorSimple  48

I Я не уверен насчет свободных и нерутированных объектов, но могу видеть, что размер мертвых объектов для живых объектов примерно такой же, как я могу видеть с помощью профилировщика, и меня больше смущает, почему объект итератора размером 48 байт выделяется в куче.

Это сторонняя библиотека, и они активно используют наборы данных, также я могу видеть, что они используют перечислители (и помещают его во время вызова для удаления).

Я хотел бы понять: 1 Это правильный путь, чтобы продолжить и любые указатели, чтобы найти причину. 2. Хотелось бы понять, почему итератор выделяется в куче, поскольку он не выглядит так, как если бы он проходил критерий с точки зрения размера. 3. Учитывая, что использование набора данных является проблемой, и это сторонняя библиотека, и я нахожусь на точке net 4.5.0 (поэтому опция сжатия кучи недоступна, пул приложений recylce также не имеет никакого эффекта) любой возможный способ обойти проблему .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...