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左右。并且执行速度也比原来的快很多。

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

时间: 2024-10-01 02:20:02

C#中XmlSerializer的内存占用问题的相关文章

cocos2dx 中切换场景内存占用过高的处理

cocos2dx 中切换场景内存占用过高的处理 1.运行场景: CCScene *pScene = HelloWorld::scene(); pDirector->runWithScene(pScene); 2.替换场景: (1) CCScene *pScene=SceneTestScene::scene(); CCDirector::sharedDirector()->replaceScene(pScene); (2) CCScene *pScene=SceneTestScene::scen

关于Android中图片大小、内存占用与drawable文件夹关系的研究与分析

从上一篇文章<Android屏幕适配全攻略>写完之后,经常会有朋友问我这个问题:"能不能一个App只提供一套切图适应所有的分辨率呢?"我觉得有必要写一篇文章来研究一下这个问题,所以就有了这篇文章. 研究内容 研究方法 测试环境 研究过程 结果分析 结论 另外一个难以解释的问题 研究内容 本篇内容主要探讨以下场景:同一张图片,放置在不同的drawable文件夹,在同一设备上运行,对图片大小及内存占用有什么影响. 研究方法 控制变量法 分析法 测试环境 采用锤子T1手机(108

[转]Android中内存占用的含义:(VSS,PSS,RSS,USS)

Android中内存占用的含义:(VSS,PSS,RSS,USS) 作者: andforce 分类: 安卓系统 发布时间: 2013-09-07 00:03 ?1,915 浏览数 6没有评论 在eng版本的android手机上,可以执行:procrank 会列出来VSS,PSS,RSS,USS的占用信息. VSS:Virtual Set Size:how virtual memory associated witth process.([共享]进程所占的虚拟内存是多少,跟物理内存没有多大关心.)

在linux下,查看一个运行中的程序, 占用了多少内存

1. 在linux下,查看一个运行中的程序, 占用了多少内存, 一般的命令有 (1). ps aux: 其中  VSZ(或VSS)列 表示,程序占用了多少虚拟内存. RSS列 表示, 程序占用了多少物理内存. 虚拟内存可以不用考虑,它并不占用实际物理内存. (2). top 命令也可以 其中  VIRT(或VSS)列  表示,程序占用了多少虚拟内存. 同 ps aux 中的 VSZ列 RES列 表示, 程序占用了多少物理内存.同 ps aux 中的RSS列 2.在linux下, 查看当前系统占用

微服务中使用 OpenJ9 JVM内存占用降低60%!

随着微服务的普及,许多企业踏上微服务之旅. 微服务化后,应用数量可能高一个数量级.一般企业,以前三五个应用能支撑业务,微服务化之后应用数量可能多达几十个.每个微服务往往独立部署,内存的消耗自然也高居不下,以前两台8核16G机器指不定就能跑起来,现两台16核64G还不一定够用,同时由于多套环境的存在加上容器编排工具(如K8s)所需的资源,硬件资源的投入自然是成倍增加. 在 Web 应用开发中,为了降低内存消耗,你是否尝试过: 去除不必要的组件,减少代码体积 更换 Web 容器,如将 Tomcat

如何分析进程的内存占用问题

一共推荐三种分析内存占用的方式 1.vmmap.exe 属于SysinternalsSuite中的工具,很强大,可以方便的查看特定进程的内存总大小(Size).内存的提交大小(Committed).内存专用工作集等(Private WS)等,也可以启动一个进程定时生成快照. 具体各名词介绍可以参考工具的help,或者参考如下文章: vmmap介绍与下载地址:https://technet.microsoft.com/en-us/sysinternals/vmmap vmmap用法介绍:http:

修改oracle内存占用

进入系统, 进入系统, # su oracle $cd $ORACLE_HOME $./sqlplus /nolog >connect / as sysdba; >show parameter sga; (查看内存占用情况) NAME TYPE VALUE ------------------------------------ ----------- ------------- lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max

pvr与png的内存占用

Zwoptex生成的spritesheet除了可以导出png格式的图片外还有pvr格式.pvr格式是iOS的显示芯片可以直接读取的,不需要经过解析就能直接显示,所以渲染速度更快,更节省内存. 我特意在cocos2D 2.0 rc1版本做了一项测试: 一个空的cocos2D模版工程运行起来之后占用的内存大约是4MB. 直接用CCSprite显示一张2048*1024的数据格式为RGBA565的PNG图片之后,内存占用达到了20MB. 同样的情况下换成pvr格式之后,内存占用为16MB.也就是说pn

C程序中常见的内存操作错误

对C/C++程序员来说,管理和使用虚拟存储器可能是个困难的, 容易出错的任务.与存储器有关的错误属于那些令人惊恐的错误, 因为它们在时间和空间上, 经常是在距错误源一段距离之后才表现出来. 将错误的数据写到错误的位置, 你的程序可能在最终失败之前运行了好几个小时,且使程序中止的位置距离错误的位置已经很远啦.而避免这种噩梦的最好方法就是防范于未然. 幸好<深入理解计算机系统>中有一段讲: C程序中常见的内存操作有关的10种典型编程错误,十分经典, 因此抄写在此, 以便以后随时查看,复习. 把优秀