Уменьшение количества потоков в приложении .NET - PullRequest
2 голосов
/ 28 апреля 2009

У меня есть средство просмотра процессов среднего размера, которое использует около 40 МБ личной памяти в Windows Vista. Проблема в том, что люди всегда сравнивают это число с объемом памяти, используемым Process Explorer и аналогичными неуправляемыми инструментами.

Я заметил, что когда моя программа простаивает, есть 13 запущенных потоков:

  • Один поток RPC (RPCRT4.dll! ThreadStartRoutine)
  • Один поток, связанный с COM (ole32.dll! CoRegisterSurrogateEx + 0x35e0)
  • Два потока ntdll (ntdll.dll! TppWorkerThread, ntdll.dll! TppWaiterpThread)
  • Основной поток GUI
  • Поток таймера (используется CLR)
  • Резьба ворот (CLR)
  • Поток отладчика (CLR)
  • 4 рабочих потока (mscorwks.dll! Thread :: middleThreadProc)
  • И, наконец, фоновый поток GDI + (gdiplus.dll! BackgroundThreadProc)

Как мне избавиться от некоторых из этих потоков, освобождая память стека потоков (по 1 МБ каждый)? ThreadPool.GetAvailableThreads говорит мне, что запущено 0 рабочих потоков, но есть 3 потока "помедленнее". Может ли использование API менеджера сервисов иметь какое-либо отношение к потоку RPC? (Он делает вызовы RPC.)

Ответы [ 2 ]

2 голосов
/ 28 апреля 2009

Одно примечание: поток с параметрами по умолчанию резервирует 1 МБ виртуальной памяти для стекового пространства. Однако вся эта память не фиксируется автоматически.

Вместо этого, если поток достигает границы последнего выделенного пространства, другая страница будет автоматически зафиксирована, пока все виртуальное пространство не будет исчерпано. Скорее всего, каждый использует намного меньше, чем 1 МБ.

См. http://msdn.microsoft.com/en-us/library/ms686774(VS.85).aspx

2 голосов
/ 28 апреля 2009

13 потоков довольно мало. К сожалению, вы не сможете избавиться от большинства этих потоков без сокращения функциональности.

Избавиться от RPC & COM, скорее всего, невозможно для управляемого приложения, и все потоки CLR, кажется, делают что-то полезное. Я предполагаю, что вы используете GDI + (возможно, через System.Drawing.) Несмотря на то, что запущено 0 рабочих потоков, пул потоков находится в режиме ожидания и готов к запуску. Вы не хотите, чтобы при публикации рабочего элемента возникали накладные расходы по созданию нового потока в незанятом процессе.

Даже если вы используете 40 МБ личной памяти, это, скорее всего, не связано с количеством потоков. Даже если каждый поток полностью использовал свой стек по умолчанию 1 МБ (чего они определенно нет, большая часть стека зарезервирована, но не зафиксирована и не будет отображаться как частные байты), то есть только 13 МБ из 40 МБ ты видишь. Можете ли вы использовать CLR Profiler, чтобы увидеть, какие выделения выполняет ваше приложение?

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