Performance Issue Caused by Crashed Finalizer Thread


 


Customer had a newly developed .NET web application hosted in IIS 6. They recently experienced some performance issues inc. slow response, high memory consumption etc. We did a first tier analysis and decided to collect IIS crash dump. After a long monitoring, we got the 2nd chance process crash dump and there the story starts from.


 


First and foremost, I found the .NET exception generated when GC did object finalization:


 # ChildEBP RetAddr 


00 01e5f9d8 79f071ac kernel32!RaiseException+0x53


01 01e5fa38 7a10733d mscorwks!RaiseTheExceptionInternalOnly+0x2a8



0b 01e5fda8 79fb99d6 mscorwks!WKS::FinalizeAllObjects+0x56


0c 01e5fdc0 79ef3207 mscorwks!WKS::GCHeap::FinalizerThreadWorker+0xe7


0d 01e5fdd4 79ef31a3 mscorwks!ManagedThreadBase_DispatchInner+0x4f


0e 01e5fe68 79ef30c3 mscorwks!ManagedThreadBase_DispatchMiddle+0xb1



14 01e5ffec 00000000 kernel32!BaseThreadStart+0x34


 


Then dumped the object stack and there are several exception objects with the same exception type “NullReferenceException” and the same message “Object variable or With block variable not set”. Tried to print the exception out which could possibly show us the call stack. However, it doesn’t work


0:012> !PrintException 3c8e19f0


Exception object: 3c8e19f0


Exception type: System.NullReferenceException


Message: Object variable or With block variable not set.


InnerException: <none>


StackTrace (generated):


<none>


StackTraceString: <none>


HResult: 80004003


 


Then I suddenly recalled that customer specially complained that the memory consumption is quite huge while I also found the crash dump size is around 1G. Quite abnormal! Plus the NullReferenceException occurred in finalizing thread, I turned around to check the finalize/dispose source code.


It turned out that CU had managed and unmanaged objects/components called in his application and he realized his own Dispose() function but didn’t suppress finalization which would let the finalization code for the object to execute a second time. Thus, NullReferenceException might occur as the object had been disposed.


 


Solution:


========


Added “GC.SupressFinalize(this)”in Dispose().


 


Reference:


Implementing Finalize and Dispose to Clean Up Unmanaged Resources


http://msdn.microsoft.com/en-us/library/b1yfkh5e(vs.71).aspx


 


Clearing up some confusion over finalization and other areas in GC


http://blogs.msdn.com/maoni/archive/2004/11/04/252697.aspx


 


Regards,


 


Yawei Wang

Comments (0)

Skip to main content