处理大型数据集和内存限制 [关闭]

Posted

技术标签:

【中文标题】处理大型数据集和内存限制 [关闭]【英文标题】:Working with large data sets and memory limitations [closed] 【发布时间】:2014-08-09 04:40:43 【问题描述】:

我正在使用一些代码来比较大型对象集合并存储所有匹配项。

不出所料,我刚刚遇到了System.OutofMemoryException

我该如何解决这个问题?

在比较期间我应该写入内存,然后让其他东西将结果写入磁盘/rdbms。即创建一个缓冲区。

【问题讨论】:

您需要将集合保存在内存中吗?也许你可以给我们看一些示例代码? 尽量在内存中同时存储尽可能少的对象。确保尽快释放所有未使用的资源。尽快将不使用的数据存储在磁盘/数据库上。当一切都尽可能优化后,然后专注于硬件。确保机器有足够的 RAM 并且应用程序池有足够的分配(如果这是托管在 IIS 上的 Web 应用程序) 【参考方案1】:

事实上,它确实取决于您的环境,尤其是 x86 或 x64 操作系统。在此处查看更多详细信息:Memory in depth

1.您有高级场景,您需要流式传输。确切的解决方案取决于您从哪里提取数据。如果从 SQL 数据库中提取数据,您可以使用与异步紧密耦合的 SqlDataReader 的流式传输,示例代码:

using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))

     if (await reader.ReadAsync())
     
         if (!(await reader.IsDBNullAsync(0)))
         
            using (var dataStream = reader.GetStream(0))
            
                //process the data
            
          
      

此链接将显示更多详细信息:Retrieving large data set。但是,请记住,这种方法会迫使您在连接字符串中使用异步以及处理异步代码,这总是会增加复杂性,尤其是当您希望通过规范/测试来覆盖它时。

2.另一种方法是批处理,即将数据缓冲到某个可接受的限制,然后将批处理公开以使用代码,然后继续获取新的一批数据,除非所有内容都已加载,示例代码:

while(true)

 int count = 0;
 bool canRead = reader.Read();
 while(canRead)
 
  canRead = reader.Read();
  count++;
  if (count >= batchSize)
   break;
 

 if (!canRead)
  break;

您可以通过估计 1 行数据的大小(基于表架构,msdn article)粗略计算批处理大小,或者只是使其可配置并使用最合适的值。这种方法的主要优点是您需要对代码进行最少的更改,并且代码本身保持同步。缺点是您必须保持活动连接或每次都打开一个新连接,而是维护您已阅读的记录以及仍需要获取的记录。

最后,这两个选项都迫使您注意一些更高级的问题,例如,如果只获取了部分数据,然后连接丢失(需要一些故障转移机制),您应该怎么做(需要一些故障转移机制),取消的能力特定超时等后长时间运行的检索操作。

总而言之,如果您不想处理大数据带来的额外复杂性,请将此任务委托给市场上可用的任何东西,即数据库或第 3 方框架。如果您觉得您的团队对此有足够的技能,那么请继续自己实现它 - 将比较结果保存在磁盘文件中,利用内存缓存或将数据推送到数据库中

【讨论】:

真棒回答谢谢【参考方案2】:

首先取决于您使用的处理器架构。如果您使用 32 位架构,则每个进程只有 2GB 内存。在这种情况下,您确实受到可以在那里存储的内容的限制。但是 64 位处理器允许更多内存,在这种情况下应该没问题。

另外需要注意的是,out of memory 异常并不意味着根本没有足够的内存,它意味着进程无法连续分配所需的内存块。如果您尝试分配一个非常大的对象,例如大小为 1GB 的数组,则进程需要为该 1GB 找到一个连续的内存块。

具体答案取决于您的情况,但通常我会先尝试切换到 64 位架构,然后查看分配的最大对象有多大。如果那里没有任何改进,您应该开始考虑将一些信息存储到磁盘。

【讨论】:

以上是关于处理大型数据集和内存限制 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

附加到大型 data.frame 并达到内存限制

将大型数据集缓存到 spark 内存中时“超出 GC 开销限制”(通过 sparklyr 和 RStudio)

php 渲染大型 zip 文件 - 达到内存限制

在htaccess中设置内存限制[关闭]

高效地为具有内存限制的神经网络训练创建 HDF5 图像数据集

JavaScript 内存限制