Case Study: OutOfMemory Exception caused by XmlSerializer is not used properly


Background

Recently we handled a case which symptom was a little bit weird: there is only an error code saying 998 without anything else. We checked the error code 998 and was told “invalid access to memory location”.  So it seems that the memory was corrupted during that time.

 

Finally, we captured dump file when the issue happened. After analysis of the dump file, we found there were huge number of temporarily assemblies like this:

61910000 61912400   vekembsq vekembsq.dll

61920000 61922400   y_uyypk7 y_uyypk7.dll

61930000 61933000   su5es57h su5es57h.dll

61940000 61942600   iap7ctus iap7ctus.dll

61950000 61952c00   qijft7hv qijft7hv.dll

61960000 61962c00   mpkdernb mpkdernb.dll

61970000 61972400   v_7j32ge v-7j32ge.dll

61980000 61983000   e3w7e9s6 e3w7e9s6.dll

61990000 61992400   6qns5_df 6qns5-df.dll

619a0000 619a2400   qesnbklg qesnbklg.dll

619c0000 619c2600   wyxnzybx wyxnzybx.dll

619d0000 619d3000   unwgrrnk unwgrrnk.dll

619e0000 619e3600   mdqqshhk mdqqshhk.dll

619f0000 619f2400   v87duh4o v87duh4o.dll

61a10000 61a13600   liw_ytyi liw-ytyi.dll

61a20000 61a23000   jb0xm8mt jb0xm8mt.dll

61a30000 61a32400   oqt4tmgy oqt4tmgy.dll

61a40000 61a42600   z6wicuee z6wicuee.dll

61a50000 61a52400   bbpqt6mn bbpqt6mn.dll

61a60000 61a63000   yicerydj yicerydj.dll

61a80000 61a82400   _bktmcil _bktmcil.dll

61a90000 61a93000   ai41tcwo ai41tcwo.dll

61aa0000 61aa2400   ptbxznda ptbxznda.dll

61ab0000 61ab2600   _u3nr50n -u3nr50n.dll

61ac0000 61ac2400   hkjoigf2 hkjoigf2.dll

61ad0000 61ad3000   ho0bdpyw ho0bdpyw.dll

61ae0000 61ae2400   rwss2wr4 rwss2wr4.dll

61af0000 61af9000   i8r6h7s8 i8r6h7s8.dll

61b10000 61b12400   _7iosnqp _7iosnqp.dll

 

We disassembled these assemblies and found all of them were  from namespace:  Microsoft.Xml.Serialization.GeneratedAssembly, which should be generated dynamically during runtime by  XmlSerializer class.

 

Actually this is a kind server side application, which will receive the request from client and serialize it using XmlSerializer according to customer’s application logic. Unlike client side application,  XmlSerializer class will be used very frequently according this kind of design.

 

Unfortunately, we found XmlSerializer was not used properly. The way XmlSerializer class is used like this:

XmlRootAttribute root = new XmlRootAttribute();

  XmlSerializer serializer = new XmlSerializer(typeof(T), root);

 

Actually, if we construct XmlSerializer object like above, a temporarily assembly will be generated for each object, and it won’t be unloaded until the application domain was shut down.  Of course, this is unacceptable for server-side application because it will result in memory leak in the end.

Suggestions

1.       To avoid countless temporary assemblies generated, you can cache the  XmlSerializer object.  

2.       Or you can construct XmlSerializer object like XmlSerializer(type) and XmlSerializer(type, defaultNameSpace) which assembly is cached naturally.

 

References

 

 Memory usage is high when you create several XmlSerializer objects in ASP.NET

http://support.microsoft.com/kb/886385/en-us

 

.NET Memory Leak: XmlSerializing your way to a Memory Leak

http://blogs.msdn.com/b/tess/archive/2006/02/15/532804.aspx

 

Best Regards,

 

Winston He from DSI Team

Comments (1)

  1. Frank Wang says:

    I tried to use XmlSerializer(Type t) to serialize a nested object of total 350 M, either to a string in memory or to a file. But I got OutOfMemoryException. My app needs to construct the XmlSerializer and to call XmlWriter only once. Is there any solution/work-around?

Skip to main content