Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 非常重的数据负载会导致foreach中出现内存不足异常_C#_List_Foreach_Out Of Memory - Fatal编程技术网

C# 非常重的数据负载会导致foreach中出现内存不足异常

C# 非常重的数据负载会导致foreach中出现内存不足异常,c#,list,foreach,out-of-memory,C#,List,Foreach,Out Of Memory,首先,我得到了这个巨大的xml文件,它表示设备收集的数据。我把它转换成一个对象。事实上,这个对象得到了一个对象列表。这些对象中有三个字符串。字符串如下所示: 012987;0,45678;... 这是一个以这种方式排列的关于表演的双重清单。每个字符串中都有1k个双精度,所以每个对象都有3k个,还有一些类似3k的对象只是为了让您了解一个典型的情况 当我读取数据时,我从OBJET中获取所有双倍数据,并将它们添加到同一列表中。我在foreach中创建了一个“包含三个double的对象”(每个字符串一个

首先,我得到了这个巨大的xml文件,它表示设备收集的数据。我把它转换成一个对象。事实上,这个对象得到了一个对象列表。这些对象中有三个字符串。字符串如下所示:

012987;0,45678;...

这是一个以这种方式排列的关于表演的双重清单。每个字符串中都有1k个双精度,所以每个对象都有3k个,还有一些类似3k的对象只是为了让您了解一个典型的情况

当我读取数据时,我从OBJET中获取所有双倍数据,并将它们添加到同一列表中。我在foreach中创建了一个“包含三个double的对象”(每个字符串一个),我获取每个对象,并将字符串拆分为数组。之后,我循环将数组转换为一个“包含三个double的对象”列表,并将其全部添加到一个列表中,以便用于进一步的操作

它会在结束之前导致内存不足异常。思想?和林克在一起最好

我得到的是这样的:


让我们做一些数学题。每个字符串1000个值*每个值8个字符(6位数字加上逗号和分号)*每个字符2个字节*每个对象3个字符串=每个对象48000个字节。这本身并不多,即使有3000个对象,我们仍然只讨论150MB左右的RAM。对于现代系统来说,这仍然算不了什么。转换为双数组甚至更少,因为每个值只有8字节,而不是16字节。字符串也是引用类型,因此在字符串版本中也会有开销。重要的是,无论您如何对其进行切分,您仍然远远没有达到85000字节的阈值保持,因此它们会被卡在大型对象堆上,这是OutOfMemoryException的正常来源

没有代码,很难准确地理解您正在做什么,但我有两种不同的猜测:

  • 字符串中的许多值都超过5位,因此您毕竟会超过神奇的85000字节阈值,并且您的对象最终会在垃圾收集器中的大型对象堆上。因此,它们不会被收集,当您继续处理对象时,很快就会耗尽地址空间(不是真正的RAM)
  • 你提取双打的方式就是一遍又一遍地重建字符串。这会给垃圾收集器造成很大的内存压力,因为它会一次又一次地重新创建字符串
  • 如果这是一个长时间运行的程序,其中每个字符串中的项目大小和数量可能会发生显著变化,那么随着时间的推移,您可能会遇到几个大值列表,这些大值将使您的对象刚好超过85000字节标记

  • 不管怎样,你们要做的就是停止列表,开始按顺序思考。尝试使用
    IEnumerable
    IEnumerable
    而不是
    List
    List
    。为字符串编写一个解析器,该解析器使用
    yield
    关键字创建迭代器块,该迭代器块将通过迭代字符从字符串中一次提取一个双精度,而不会更改字符串。这将更好地执行,并可能解决您的内存问题。

    也许您可以发布代码;)段落也会使阅读更容易。:)3k*3加倍~250k字节,不足以存储OOM3k对象*(3k*3)数据=750MB扫描是否使用xml数据的顺序读取?甚至可能在一个完整对象和数据的子范围内工作?我最终决定回顾这个循环。里面的手术太多了。现在它工作得很好,但我不得不重新考虑整个事情,以便在其中转换最少的数据。我并没有完全使用你的解决方案,但通过阅读它可以明显看出我的方式有问题,所以谢谢。