C#中XmlSerializer的内存占用问题

被XmlSerializer掉坑里了,爬了一晚上才出来。

本来实现一个功能,从数据库中查出一堆数据(比较多,几十万,不过,是分批查出来的),查出来的数据包含了一个XML字符串,代码中对其进行序列化,一开始的代码是这样写的:

            string xmlString = "<root>" +
                               "<Employee><Name>张三</Name><Age>20</Age><Address>深圳南山</Address></Employee>" +
                               "<Employee><Name>李四</Name><Age>22</Age><Address>深圳南山</Address></Employee>" +
                               "</root>";
            //string xmlString2 = "<Employee><Name>张三</Name><Age>20</Age><Address>深圳南山</Address></Employee>";

            for (var i = 0; i < 100000; i++)
            {
                byte[] bytes = System.Text.Encoding.GetEncoding("utf-8").GetBytes(xmlString);
                using (var stream = new MemoryStream(bytes))
                {
                    try
                    {
                        XmlSerializer xz1 = new XmlSerializer(typeof(Employee), new XmlRootAttribute("root"));
                        //XmlSerializer xz1 = new XmlSerializer(typeof(Employee));
                        var r = (Employee)xz1.Deserialize(stream);
                    }
                    finally
                    {
                        stream.Close();
                        stream.Dispose();
                    }
                }
                Console.WriteLine(i);
            }
            Console.Read();

  看起来没什么问题,不过,一到正式环境运行了几次这个几十万就完蛋了,内存直线上升,我在本地模拟了一下(就是上面的代码撒),这么一段小小的反序列化,一会进程就占用了近1G的空间,并且代码跑完也不会自动回收,测试使用GC进行回收,也没有用。后来在微软的官网找到帮助文档(https://support.microsoft.com/en-us/kb/886385)

在打开某度翻译的前提下,把这篇文章看懂了,大概意思是:

现象:当创建一些XmlSerializer对象时,内存会异常增加。

引起的原因:当创建这个对象时,会动态的加载一些程序集,但是我们又不可以手动销毁这些程序集,就会导致在创建N多个XmlSerializer时,内存会占用很多。

解决办法:

1、使用缓存,即把每次创建的XmlSerializer对象使用某种方式(Cache,或者Static)进行缓存,下次就不再创建了。

2、使用如下的构造函数:

public XmlSerializer(Type type);
public XmlSerializer(Type type, string defaultNamespace);

例如上面的代码中注释掉的部分,就是使用第一个构造函数。使用这种方式,这个小Demo中,内存也只占用10M左右。并且执行速度也比原来的快很多。

 

总觉得这个功能太坑了,看了一下系统中的代码,包含原来的老代码,都是存在内存的问题,不过,原来没有集中声明对象的场景,所以没有出现,偶尔出来服务挂了,也不知道什么 原因,反正系统又自动重启了,就遗留观察吧,然后就一直观察下去,没下文了。。。

 

posted @ 2016-01-22 18:21  WileyWong  阅读(1716)  评论(0编辑  收藏  举报