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

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

 

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

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

 

Best Regards,

 

Winston He from DSI Team