Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: C# - утечка памяти - большое количество потоков Добавлено: 15.02.12 23:24  

Автор вопроса:  Programmer
Программа использует ThreadPool.
Вовремя её работы постепенно увеличивается количество потоков до макс 1027, расход виртуальной памяти до 1,5 гб.
Расход реальной памяти не превышет 150 мб.

Профайлеры этого в принципе не видят. Говорят про расходы в рамках 70 мб :)

Использовал встроенный и Sci профайлеры памяти.

Может ли большой расход памяти быть связан с таким количеством потоков? Как это установить?

Ответить

  Ответы Всего ответов: 8  

Номер ответа: 1
Автор ответа:
 Programmer



Вопросов: 71
Ответов: 246
 Профиль | | #1 Добавлено: 15.02.12 23:28
Программа работает с сокетами, принимает асинхронно. Сокетов 10к штук. Передают и принимают данные раз в 3 секунды.

В диспетчере задач потребление памяти и количество потоков увеличивается приблизительно по 1 мб в секунду и 1 потоку в секунду. Тестировал с 500 сокетами, расход памяти такой же. А на 10 - не заметно.

Ответить

Номер ответа: 2
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #2 Добавлено: 19.02.12 07:28
количество потоков до макс 1027

сокетами, принимает асинхронно

Взаимоисключающие параграфы?

Тут на самом деле все просто - на каждый поток выделяется по 1 мегабайту памяти для стека, ну и еще немного для хранения контекстов. Так что никакой утечки в твоем случае похоже что нет.

Я бы на твоем месте перед тем, как писать приложение под нагрузку 10К конкурентных клиентов, все-таки немного подучился бы, как вобщем принципам разрабокти серверных приложений под высокую нагрузку, так и в частности, механизмам работы системы ввода-вывода в .NET

Ответить

Номер ответа: 3
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #3 Добавлено: 19.02.12 07:40
Если по сути - корректная асинхронная работа с сокетами не приведет к такому расходу потоков. Похоже что в твоей реализации под каждый поток запускается 1 поток (что вобщем делает невозможной обработку 10К клиентов). Такого быть не должно. Для напиши реализацию, которая вообще не использует ThreadPool и Thread прямо или косвенно (то есть также без Task'ов и т.п.).

Ответить

Номер ответа: 4
Автор ответа:
 Programmer



Вопросов: 71
Ответов: 246
 Профиль | | #4 Добавлено: 19.02.12 21:52
Клиентов уже 50К (нашел, как обойти ограничение винды), полет стабильный, но на клиентах Out Of Memory через 5 минут) Потоки создаются ThreadPool-ом при использовании асинхронных функций сокета. Я вроде бы нашел в чем дело, только до конца не понимаю, почему тогда количество потоков растет так медленно.

А дело в том, что в моем функции AsyncCallback, которую я передаю на вызов BeginRecieve сокета, (естественно, когда ar.IsCompleted) я делаю Thread.Sleep на 35 мс и оттуда же вызываю следующий BeginRecieve. Так вот, пока работает Sleep поток ThreadPool-а занят, а он вынужден создавать новый поток для другого сокета, вызывающего во то же время у себя BeginRecieve.

Я вот думаю, а может быть мне сделать статический таймер, который будет по очереди вызывать BeginRecieve всех сокетов, у которых прием закончен и истек таймаут в 35 мс?

Сейчас сделал такое: внутри моего AsyncCallback я вызываю отдельную функцию обработки приема данных (в которой Sleep) через ThreadPool, тем самым мгновенно освобождаю текущий IO поток. Это уменьшило количество потоков, но и значительно увеличило время отклика сервера (на 3К клиентах передавать данные каждые 130 мс уже не получается, но на 10К данные передаются раз в 3 секунды, так что это не заметно).

Ответить

Номер ответа: 5
Автор ответа:
 Programmer



Вопросов: 71
Ответов: 246
 Профиль | | #5 Добавлено: 19.02.12 22:14
Так же есть такая странность: клиенты (по 10К, 5 штук) создают гораздо больше потоков, чем сервер....

Ответить

Номер ответа: 6
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #6 Добавлено: 20.02.12 01:54
Показывай код, нужно смотреть.

Еще раз - 50К клиентов грубо говоря можно обрабатывать всего несколькими потоками (если они не сильно активно шлют данные), или чуть больше, в пределах десятка штук, но никак не тысяча! Память будет тратиться только на хранение объектов ядра, связанных с сокетами (оч. мало), на буферы сокетов (по дефолту, кажется, по 8 кб на сокет).

Я вроде бы нашел в чем дело, только до конца не понимаю, почему тогда количество потоков растет так медленно.

В Thread Pool есть ограничение на кол-во запусков новых потоков в секунду. Поэтому если в Tread Pool попадет сразу 1000 новых заданий, это не значит что он сразу запустит 1000 потоков, он будет кол-во работающих поотков наращивать постепенно. Причина - предполагается что Thread Pool используется для низкоприоритетных задач (таких как обработка ввода-вывода, например), а одновременный запуск большого кол-ва потоков сильно повредит быстродействию приложения. Посчитали - лучше если низкоприоритетные задачи подождут, но визуально быстродействие не пострадает.

Если нужен относительно гарантированный тайминг запуска потоков - тогда нужно использовать Thread напрямую.

Ответить

Номер ответа: 7
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #7 Добавлено: 20.02.12 02:02
Programmer пишет:
Так же есть такая странность: клиенты (по 10К, 5 штук) создают гораздо больше потоков, чем сервер....

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

Я через все это проходил. В итоге у меня получился сервер, который без проблем держал 32 или 64 тысячи одновременных подключений.
Был тестовый клиент, который мог имитировать действия одновременно нескольких тысяч реальных клиентов.

Все это без таких затрат ресурсов как у тебя.

Если интересно, напиши в скайп artyom_kr.

Ответить

Номер ответа: 8
Автор ответа:
 Programmer



Вопросов: 71
Ответов: 246
 Профиль | | #8 Добавлено: 20.02.12 19:22
Проблему уже решил, спасибо, что навел на мысль. Оказалось, в клиенте была еще одна аналогичная штука с Thread.Sleep-ом.

Напишу)

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам