日期:2014-05-20  浏览次数:21207 次

linq内存
C# code

while (has)
            {
                var data = (from p in db.数据表s
                            where p.时间 > lastfinaltime && p.时间 < DateTime.Now       //将新导入的记录导出来。
                            orderby p.时间 ascending
                            select p).Skip(skipp).Take(2000);
                skipp += 2000;
                if (data.Count() == 2000)
            .....
                 if(......)
                 has=false//数据处理结束


 由于数据繁多,处于耗费巨大内存这一方面。所以我想这样每次取出一部分数据再逐一处理。但是我发现,在运行期间,内存还是一步一步加上来了,请问大家有什么好的方法,能将每次取的数据所占的内存释放掉啊,要不然这样skip().take()这不是白折腾么? 谢谢各位!

------解决方案--------------------
如果没用到非托管,也没有申明"全局"变量,

不用过于担心,只要你一次不是取太多的资料,造成内存溢出.不需要去担心程式运行中内存不断增加的问题.

过段时间GC会自动回收不使用的部分的.
------解决方案--------------------
if (data.Count() == 2000)
==========
原因 在这句代码
因为 Count() 是非延迟查询操作符
它会将data集合内的所有数据都加载到内存中
------解决方案--------------------
问题不是出在 SKIP TAKE
因为SKIP TAKE都是延迟查询操作符
------解决方案--------------------
没有必要判断。

因为 linq 的 take 以及 skip 会自动处理数据不足的情况。
------解决方案--------------------
Assembly code


·Select - Select选择;延迟
·Where - Where查询;延迟
·OrderBy - 按指定表达式对集合正序排序;延迟
·OrderByDescending - 按指定表达式对集合倒序排序;延迟
·GroupBy - 分组;延迟
·Join - Join查询;延迟
·GroupJoin - 分组Join查询;延迟
·Distinct - 过滤集合中的相同项;延迟
·Union - 连接不同集合,自动过滤相同项;延迟
·Concat - 连接不同集合,不会自动过滤相同项;延迟
·Intersect - 获取不同集合的相同项(交集);延迟
·Except - 从某集合中删除其与另一个集合中相同的项;延迟
·Skip - 跳过集合的前n个元素;延迟
·Take - 获取集合的前n个元素;延迟
·SkipWhile - 直到某一条件成立就停止跳过;延迟
·TakeWhile - 直到某一条件成立就停止获取;延迟
·Single - 根据表达式返回集合中的某一元素;不延迟
·SingleOrDefault - 根据表达式返回集合中的某一元素(如果没有则返回默认值);不延迟
·Reverse - 对集合反向排序;延迟
·SelectMany - Select选择(一对多);延迟
·First - 返回集合中的第一个元素;不延迟
·FirstOrDefault - 返回集合中的第一个元素(如果没有则返回默认值);不延迟
·Last - 返回集合中的最后一个元素;不延迟
·LastOrDefault - 返回集合中的最后一个元素(如果没有则返回默认值)
·ElementAt - 返回集合中指定索引的元素;不延迟
·ElementAtOrDefault - 返回集合中指定索引的元素(如果没有则返回默认值);不延迟
·Contains - 判断集合中是否包含有某一元素;不延迟
·Any - 判断集合中是否有元素满足某一条件;不延迟
·All - 判断集合中是否所有元素都满足某一条件;不延迟
·Count - 返回集合中的元素个数,返回int;不延迟
·LongCount - 返回集合中的元素个数,返回long;不延迟
·Sum - 集合应为数字类型集合,求其和;不延迟
·Min - 返回集合的最小值;不延迟
·Max - 返回集合的最大值;不延迟
·Average - 集合应为数字类型集合,求其平均值;不延迟
·Aggregate - 根据输入的表达式获取一个聚合值;不延迟
·Cast - 将集合转换为强类型集合;延迟
·DefaultIfEmpty - 查询结果为空则返回默认值;延迟
·SequenceEqual - 判断两个集合是否相同;不延迟
·OfType - 过滤集合中的指定类型;延迟
·ToArray - 将集合转换为数组;不延迟
·ToList - 将集合转换为List<T>集合;不延迟
·ToDictionary - 将集合转换为<K, V>集合;不延迟

------解决方案--------------------
你用Sql Profile 录一下你这个Linq所产生的T-SQL语句再来看看会不会造成内存不足

用VS2008以上的版本执行LoadTest,进行负载测试看看,会不会有内存不足的问题.

"能将每次取的数据所占的内存释放掉啊" 
至于这个问题,在第一楼说了:"如果没用到非托管,也没有申明"全局"变量,不用过于担心,只要你一次不是取太多的资料,造成内存溢出.不需要去担心程式运行中内存不断增加的问题.过段时间GC会自动回收不使用的部分的."

不知道楼主还在纠结个肾?

这个话题你发了好像不下3个帖子了.

探讨

原来的数据有几百万条,一定要用到data.count(),因为不知道里面到底有多少条记录,所以我就采取这种方式。我想着每次重新取数据的时候就能把以前的数据所占的内存释放掉的,可是事与愿违啊......