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.
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.
Memory usage is high when you create several XmlSerializer objects in ASP.NET
.NET Memory Leak: XmlSerializing your way to a Memory Leak
Winston He from DSI Team