I have effectively this code (it looks insane with all those try
-catch
es 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?
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".
User contributions licensed under CC BY-SA 3.0