2

我有效地拥有这段代码(所有这些看起来很疯狂try- catches 但我真的需要它们来说明问题):

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 对象驻留在进程外服务器进程中。客户端和 COM 服务器都在 Azure Web 角色中运行,我不知道在 Azure 之外是否会再次发生相同的行为。

大多数时候它只是工作 -DoStuff()运行正常,然后Cleanup()运行正常。有时在某些特定数据集上DoStuff()产生System.OutOfMemoryException,然后Cleanup()运行并产生System.Runtime.InteropServices.COMException错误代码0x800700A4,该代码对应ERROR_MAX_THRDS_REACHED于 winerror.h 中的定义并具有文本“系统中无法创建更多线程”。枚举所有进程的代码运行并且没有进程具有任何不合理的线程数,并且托管 COM 服务器的进程的线程数等于 3(是的,只有 3 个)。

一旦ERROR_MAX_THRDS_REACHED发生,对该 COM 服务器的所有调用也会产生ERROR_MAX_THRDS_REACHED,直到 COM 服务器重新启动。

ERROR_MAX_THRDS_REACHED当没有明显的螺纹泄漏时会导致什么?

4

1 回答 1

2

经过大量观察,很明显,在大多数情况下,该问题被重现,COM 服务器进程将消耗几乎所有内存(COM 服务器是一个 32 位进程,因此它不能消耗超过 2 GB 的内存)。

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

我没有证据证明它确实是这样工作的,但这是我能想到的最好的解释。看起来这只是内存短缺,阻止了新线程的创建并被报告为“无法创建更多线程”。

于 2013-11-08T08:35:36.253 回答