减少.NET应用程序内存占用的一则实践

  次阅读 作者:智能小宝 来源:互联网 2016-01-27 15:25 我要评论(0)

最近一周比较忙,主要的工作内容是在做一个叫 键盘精灵 的东西,简单来讲就是将很多数据放到内存中,对这些数据进行快速检索,然后找出根据输入条 件最匹配的10条记录并予以展示。具体和下面两款炒股软件的相关功能类似:

数据以文本形式存在文件中,且数据量较大,有近20万条,每一条记录有几个字段,以分隔符分割。当时使用的是6万条记录的测试数据,文本文件将 近 10M,这个模块加载到内存并建立缓存之后,大概会占用将近70-80M的内存。自我接手以后,主要的任务就是降低内存消耗和提高匹配效率。

一、避免创建不必要的对象

拿到代码后,第一步就是看设计文档,然后断点一步一步的看代码,大概明白了逻辑之后,发现思路有一些问题。之前的代码处理流程思路大概是下面这 样的:

1.将文件读取到内存,实例化

2.根据条件对文件进行检索,并存储到结果集1中

3.对结果集1中的结果进行匹配度计算,并存储到结果集中2

4.按对结果集2进行匹配度排序,取最匹配的10条记录,然后返回

这个过程中规中矩。但是其中有很多问题,最大的问题是,临时变量存储了太多的中间处理结果,而这些对象在一次查询完成后又马上丢弃,大量的临时 对象带来了很大的GC压力。举例来说,当用户在输入框中输入1的时候,假设使用Contains来匹配,那么从6万条记录中找出包含1的记录可能有4万多 条,然后需要把这4万多条记录存储在临时变量中进行处理,进一步计算这4万条记录的匹配度,然后存储到一个类似KeyValuePair的集合中,key 为匹配度,然后对这个集合按Key进行排序,然后取前10条最优记录。可以看到,中间创建了大量的临时变量,使得内存剧增,大量临时对象创建之后马上会被 回收,GC压力山大。

而在设计文档中,只要求返回最最匹配的10条记录,之前的解决方案中似乎并没有注意到这一点。所以接手后,第一步就是对上面的处理过程进行精 简。精简后如下:

将文件读取到内存,实例化

根据条件对文件进行检索,如果存在,则:

计算匹配度。

以匹配度为Key,存储到只有11个容量的SortList中。

如果SortList集合添加记录后大于10个,则移除最后面一个元素,始终保持着前10个最小(匹配度最优)的记录。

遍历完成之后,返回这个集合对象

经过这一修改,减少了大量临时数据对内存的占用,整个过程中,我只是使用一个容量为11的SortList结构存储中间的过程,每一次插入一个 元素,SortList帮我们排好序,然后移除最不匹配的那一个,也就是最后一个元素(从小到大排序,越匹配,值越小)。这里面的消耗主要是 SortList的插入,内部排序和移除记录。 说到这里在选择SortList还是SortDictionary的问题上纠结了一下,于是又找了些资料,SortDictionary在内部使用红黑树 实现,SortList采用有序数组实现, 在内部排序都为O(logn)的前提下,SortDictionary的O(logn)插入及删除元素的时间复杂度优于SortList,但是 SortDictionary会比SortList占用更多内存。基本来说这是一个查询速度和内存分配之间的平衡,由于这里只需要存储11个对象,所以两 者相差不大。其实即使没有这种结构,自己也可以实现的,无非就是一个集合,每次添加一个,排好序,然后将最大的那个移除。.NET使用起来方便是因为有很 多这些强大的内置数据结构。

经过上面这个小小的修改,内存占用一下子降低了1倍,从原来的70-80M,降低到了30-40M,其实这就是降低内存开销的一个最基本的原 则,那就是避免创建不必要的对象。

二、优化数据类型及算法

越到后面内存的降低越来越困难。仔细看了代码之后,除了上面之外,代码中也有一些其他问题,比如,一开始就将大量的对象实例化到内存中,然后一 直保存。每一条记录中的信息比较多,但真正有用的用于搜索匹配的只有下面四个字段,但是整体的实例化会将其他没有用的字段也一并序列化进去了。导致很多内 存被无用的字段占用。

股票代码 股票中文名 中文拼音 市场类型

600000 浦发银行 PFYH 上证A股

所以第一步就是在内存中只存放需要检索的上面四个关键字段,每一条记录刚开始是使用string[]数据,而不是使用类或者其它结构来保存,也 尝试使用结构提来保存,但是由于四个字段,数据量大,中间还要作为参数传递,所以比使用类还大,这里只是简单的使用了数组。

除了上面这些之外,为了提高搜索效率,对数据按照0-9,a-z开头对数据做了切分分块缓存,这样当用户输入0时,直接从以0为key的块中读 取数据,这样速度是加快了,但是大量的缓存也增加了对内存的消耗。缓存的数据基本上和加载到内存中原始的数据一样大了。并且在搜索的过程中,也是采用的完 全搜索,对于17万条数据的四个字段,每一次查询要进行170000*4次遍历比较,才能找出最匹配的10条数据来。

本站文章信息来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如果您有什么意见或建议,请联系QQ28-1688-302!

人工智能实验室
相关文章相关文章
  • 韩春雨称已能重复实验结果 近期将有消息公布

    韩春雨称已能重复实验结果 近期将有消息公布

  • 未来两年人工智能要怎么走?看这篇就够了

    未来两年人工智能要怎么走?看这篇就够了

  • 英国研发“杀生”机器人 通过生命体获取能量

    英国研发“杀生”机器人 通过生命体获取能量

  • 无人驾驶汽车如何改变城市生活?听听他们怎么说

    无人驾驶汽车如何改变城市生活?听听他们怎么说

网友点评网友点评
阅读推荐阅读推荐

据国外媒体报道,在过去两年内,聊天机器人(chatbot)、人工智能以及机器学习的研发和采用取得了巨大进展。许多初创公司正利用人工智能和...

霍金 视觉中国 图 英国著名物理学家霍金(Stephen Hawking)再次就人工智能(AI)发声,他认为:对于人类来说,强大AI的出现可能是最美妙的...

文|郑娟娟 今年,人工智能(AI) 60岁了。在AI60岁的时候,笔者想要介绍一下AI100,一个刚刚2岁的研究项目,但它的预设寿命是100年,甚至更长...

AlphaGo与李世石的人机大战,为大众迅速普及了人工智能的概念。 但对谷歌而言,除了下围棋,现在的人工智能进展到哪一步了?未来,人工智能...