减少.NET应用程序中的线程数量

时间:2009-04-28 01:25:51

标签: c# multithreading memory

我有一个中等大小的进程查看器,它在Windows Vista上使用大约40MB的私有内存。问题是人们总是将这个数字与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 :: intermediateThreadProc)
  • 最后是一个GDI +后台线程(gdiplus.dll!BackgroundThreadProc)

如何摆脱其中一些线程,释放线程堆栈内存(每个1MB)? ThreadPool.GetAvailableThreads告诉我有0个工作线程在运行,但是有3个“intermediateThreadProc”线程。可以使用服务管理器API与RPC线程有什么关系吗? (它会进行RPC调用。)

2 个答案:

答案 0 :(得分:2)

13个线程非常低。不幸的是,如果不削减功能,你将无法摆脱大部分线程。

摆脱RPC&对于托管应用程序来说,COM很可能是不可能的,并且CLR线程似乎都在做一些有用的事情。我猜你正在使用GDI +(可能是通过System.Drawing。)即使有0个工作线程正在运行,线程池也有“待机”线程,准备启动。您不希望发布工作项必须承担在空闲进程中创建新线程的开销。

即使你可能正在使用40 MB的私有内存,这很可能不是由于线程的数量。即使每个线程完全使用它的1 MB默认堆栈(它们肯定不是,大多数堆栈都是保留但未提交但不会显示为私有字节),这只是40 MB的13 MB你看到了。您可以使用CLR Profiler查看您的应用程序正在进行哪些分配吗?

答案 1 :(得分:2)

一个注意事项:具有默认选项的线程为堆栈空间保留1MB的虚拟内存。但是,所有内存都不会自动提交。

相反,如果线程刚刚超过已提交空间的边缘,则将自动提交另一个页面,直到所有虚拟空间都耗尽为止。最有可能的是,每个使用的数量都少于1MB。

请参阅 http://msdn.microsoft.com/en-us/library/ms686774(VS.85).aspx