Why is E_OUTOFMEMORY followed by "no more threads can be created"?

2

I have effectively this code (it looks insane with all those try-catches but I really need them to illustrate the problem):

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;
   }
}

The COM object resides in an out-proc server process. Both the client and the COM server run inside Azure web role and I don't know whether the same behavior would reoccur outside Azure.

Most of the time it just works - DoStuff() runs okay, then Cleanup() runs okay. Sometimes on some specific datasets DoStuff() yields System.OutOfMemoryException and then Cleanup() runs and yields System.Runtime.InteropServices.COMException with error code 0x800700A4 which corresponds to ERROR_MAX_THRDS_REACHED define in winerror.h and has text "No more threads can be created in the system`. The code that enumerates all processes runs and none of the processes has any unreasonable treads count and the process hosting the COM server has thread count equal to 3 (yes, just three).

Once ERROR_MAX_THRDS_REACHED happens all the calls to that COM server also yield ERROR_MAX_THRDS_REACHED until the COM server is restarted.

What could cause ERROR_MAX_THRDS_REACHED when there's no obvious leakage of threads?

.net
com
windows-server-2008-r2
azure-web-roles
asked on Stack Overflow Aug 29, 2013 by sharptooth • edited Aug 30, 2013 by sharptooth

1 Answer

2

After much observation it's clear that in most cases the issue is reproduced the COM server process will have almost all memory consumed (the COM server is a 32-bit process so it can't consume more that 2 gigabytes of memory).

This likely happens because of memory fragmentation or memory leak - hard to say without further analysis. This in turn likely leads to not enough memory to create a new thread (which is needed to serve the COM client request) and the latter is likely being diagnosed as "no more threads can be created" instead of "not enough memory" in the COM server (that error code is returned to the client and observed by the client).

I have no proof that it works exactly this way but this is the best explanation I can come up with. It looks like it's just memory shortage preventing new threads creation and being reported as "no more threads can be created".

answered on Stack Overflow Nov 8, 2013 by sharptooth

User contributions licensed under CC BY-SA 3.0