博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
避免创建不必要的对象减少.NET应用程序内存占用
阅读量:4597 次
发布时间:2019-06-09

本文共 1305 字,大约阅读时间需要 4 分钟。

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

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,其实这就是降低内存开销的一个最基本的原则,那就是避免创建不必要的对象

转载于:https://www.cnblogs.com/haosola/archive/2013/03/16/2962479.html

你可能感兴趣的文章
shell-逐行读取文件
查看>>
贝叶斯如何生效
查看>>
UVA - 1588 - Kickdown
查看>>
Win32 SDK:ListBox 为什么不整个 LB_SETTEXT
查看>>
spring的优缺点
查看>>
优云老王的心路历程(一):那个做了五年的产品经理
查看>>
双态运维分享之:业务场景驱动的服务型CMDB
查看>>
cocos2dx-3.6 触摸,键盘,聚焦事件
查看>>
JEECG中t:dictSelect的extendJson用法
查看>>
web开发下的各种下载方法
查看>>
第六章 堆排序 6.5 优先队列
查看>>
Linux搭建我的世界服务器
查看>>
数据库之范式
查看>>
译文 [ROM][多国语言][2015.06.11] Lenovo S750 (MTK6589) - andrea_d86-lenovos750-4.2.2
查看>>
租用游艇问题
查看>>
如何修改SharePoint 2010默认的任务通知邮件的格式?
查看>>
单用户模式下连接被占用定位spid
查看>>
Django JWT
查看>>
云推送注意(MSDN链接)
查看>>
条件编译解决AutoCAD多版本问题
查看>>