.NET 2.0 ThreadPool线程堆栈增加导致内存不足(达到提交限制)

时间:2018-06-08 18:40:09

标签: .net out-of-memory threadpool windows-7-embedded vmmap

操作系统:Windows 7 Embedded

RAM :1 GB

分页文件大小:500 MB

剩余磁盘空间:~1 GB

.NET :2.0

我正在开发一个用C#编写的.NET 2.0 Winforms应用程序,该应用程序在Windows 7 Embedded上运行,其中系统只有1 GB的RAM,而且可用磁盘空间相当有限(约1 GB)。我们正在从Windows XP Embedded迁移到Windows 7 Embedded,虽然我们的程序在Windows XP上运行良好,但由于Windows 7上的内存不足,它已多次失败。我们在故障后添加了500 MB的页面文件( Windows 7 Embedded的默认值似乎是0MB的页面文件大小)。但是,因为我们已经缩小了由程序提交的内存增加引起的内存不足异常,所以即使使用分页文件,也可能在足够长的时间内达到系统提交限制。我们无法快速将硬件迁移到更合适的位置,并且必须找到可在下一版本之前解决问题的软件解决方案。

使用SysInternals VMMap工具,我们可以看到程序虚拟内存中线程堆栈的数量随着时间的推移缓慢增加,最终导致程序提交的内存导致系统超出其提交限制时失败。线程堆栈增加的原因已被隔离到.NET 2.0 ThreadPool,由于某种原因,它会随着时间的推移创建一个净正数线程。我们认为这是因为在我们的代码中过度使用了System.Timers.Timer类,每个实例在ThreadPool上运行其定时器已用事件处理程序,尽管仍然不清楚为什么ThreadPool保持这么多线程,即使假设定时器回调并不总是使用它们。其中一些事件处理程序处理信息的时间比ThreadPool线程的理想时间长,最差的违规者甚至调用Thread.Sleep()。

我们已经考虑了几个可能的解决方案来解决这个问题,包括限制ThreadPool工作线程的数量,交换更长时间运行的线程计时器回调,以及迁移到更高版本的.NET。最后一个解决方案假设已经通过.NET的迭代对ThreadPool管理器进行了优化,这可能有助于缓解问题。我们错过了其他明显(或非显而易见)的解决方案吗?

编辑:进一步检查时,生成并粘贴的ThreadPool线程具有以下调用堆栈:

ntdll!KiFastSystemCallRet 
ntdll!ZwWaitForSingleObject+c 
KERNELBASE!WaitForSingleObjectEx+98 
kernel32!WaitForSingleObjectExImplementation+75 
mscorwks!PEImage::LoadImage+1af 
mscorwks!CLREvent::WaitEx+117 
mscorwks!CLREvent::Wait+17 
mscorwks!ThreadpoolMgr::SafeWait+73 
mscorwks!ThreadpoolMgr::WorkerThreadStart+11c 
mscorwks!Thread::intermediateThreadProc+49 
kernel32!BaseThreadInitThunk+e 
ntdll!__RtlUserThreadStart+70 
ntdll!_RtlUserThreadStart+1b 

0 个答案:

没有答案
相关问题