为什么E_OUTOFMEMORY后跟“不能再创建线程”?

时间:2013-08-29 15:17:31

标签: .net com windows-server-2008-r2 azure-web-roles

我有效地使用了这段代码(对于所有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

1 个答案:

答案 0 :(得分:2)

经过多次观察后很明显,在大多数情况下,问题再现了COM服务器进程将消耗几乎所有内存(COM服务器是一个32位进程,所以它不能消耗更多的2 GB内存)。

这可能是因为内存碎片或内存泄漏 - 很难说没有进一步的分析。这反过来可能导致没有足够的内存来创建新线程(这是为COM客户端请求提供服务所需的),而后者可能被诊断为“不能创建更多线程”而不是“没有足够的内存”。 COM服务器(将错误代码返回给客户端并由客户端观察)。

我没有证据证明它的确如此,但这是我能想到的最佳解释。它看起来只是因为内存短缺阻止了新线程的创建,并被报告为“不再创建线程”。