我有效地使用了这段代码(对于所有try
- catch
es看起来很疯狂,但我真的需要它们来说明这个问题):
Exception doStuffException = null;
try {
someComObject.DoStuff();
} catch( Exception e ) {
doStuffException = e;
throw;
} finally {
try {
someComObject.Cleanup();
} catch( Exception e ) {
var processes = Process.GetProcesses();
foreach( var p in processes ) {
//log p.Threads.Count and p.ProcessName
}
throw;
}
}
COM对象驻留在out-proc服务器进程中。客户端和COM服务器都在Azure Web角色中运行,我不知道在Azure之外是否会再次发生相同的行为。
大部分时间它都可以运行 - DoStuff()
运行正常,然后Cleanup()
运行正常。有时在某些特定数据集上DoStuff()
会产生System.OutOfMemoryException
,然后Cleanup()
会运行并产生System.Runtime.InteropServices.COMException
,错误代码0x800700A4
对应于ERROR_MAX_THRDS_REACHED
在winerror中定义.h并且有文本“系统中不能创建更多的线程。”枚举所有进程的代码运行,没有任何进程有任何不合理的步数,托管COM服务器的进程的线程数等于3(是的,只有三个。)
一旦ERROR_MAX_THRDS_REACHED
发生,对该COM服务器的所有调用也会产生ERROR_MAX_THRDS_REACHED
,直到COM服务器重新启动。
当没有明显的线程泄漏时,什么可能导致ERROR_MAX_THRDS_REACHED
?
答案 0 :(得分:2)
经过多次观察后很明显,在大多数情况下,问题再现了COM服务器进程将消耗几乎所有内存(COM服务器是一个32位进程,所以它不能消耗更多的2 GB内存)。
这可能是因为内存碎片或内存泄漏 - 很难说没有进一步的分析。这反过来可能导致没有足够的内存来创建新线程(这是为COM客户端请求提供服务所需的),而后者可能被诊断为“不能创建更多线程”而不是“没有足够的内存”。 COM服务器(将错误代码返回给客户端并由客户端观察)。
我没有证据证明它的确如此,但这是我能想到的最佳解释。它看起来只是因为内存短缺阻止了新线程的创建,并被报告为“不再创建线程”。