gpt4 book ai didi

c# - 为什么我会收到 System.OutOfMemoryException

转载 作者:太空宇宙 更新时间:2023-11-03 13:23:21 27 4
gpt4 key购买 nike

我正在使用 Linq to Sql。这是代码:

Dictionary<string, int> allResults;
using (var dc= new MyDataContext())
{
dc.CommandTimeout = 0;
allResults = dc.MyTable.ToDictionary(x => x.Text, x => x.Id);
}

它在 64 位机器上运行,编译是 AnyCPU。它抛出 System.OutOfMemoryException。

这会访问 SQL Server 数据库。 Id 字段映射到 SQL Server int 字段,Text 字段映射到 Text(nvarchar(max)) 字段。运行 select COUNT(*) from TableName 得到 1,173,623 条记录,运行 select sum(len(Text)) from TableName 得到 48,915,031 条记录。由于 int 是一个 32 位整数,id 应该只占用 4.69MB 的空间,字符串应该不到 1GB。所以我们甚至没有违反 2GB/对象的限制。

然后我以这种方式更改代码:

Dictionary<string, int> allResults;
using (var dc = new MyDataContext())
{
Dictionary<string, int> threeHundred;
dc.CommandTimeout = 0;
var tot = dc.MyTable.Count();
allResults = new Dictionary<string, int>(tot);
int skip = 0;
int takeThis = 300000;
while (skip < tot)
{
threeHundred = dc.MyTable.Skip(skip).Take(takeThis).ToDictionary(x => x.Text, x => x.Id);
skip = skip + takeThis;
allResults = allResults.Concat(threeHundred).ToDictionary(x => x.Key, x => x.Value);
threeHundred = null;
GC.Collect();
}
}

我了解到这里的垃圾收集没有帮助,一旦 skip = 900,000,就会在 while 循环的第一行抛出内存不足异常。

出了什么问题,我该如何解决?

最佳答案

在不考虑应该占用多少内存的情况下(因为可能存在编码问题,很容易使数据大小加倍),我将尝试提供一些建议。

从问题的原因开始 - 我的猜测是 threeHundred 字典导致了大量分配。当您像上面那样将项目添加到字典时,字典将无法知道它应该预先分配多少项目。这将导致大量重新分配和处理所有数据到新创建的字典。在向 threeHundred 字典添加任何项目之前,请设置一个大小(使用 ctor)。

请阅读我发表的这篇深入探讨词典内部结构的文章 - 我相信它会阐明这些症状。 http://www.codeproject.com/Articles/500644/Understanding-Generic-Dictionary-in-depth

此外,当尝试填充如此大量的数据时,我建议完全控制过程。我的建议:

  • 在 Dictionary 中预分配插槽(直接在 DB 上使用 Count 查询,并将其传递给 Dictionary ctor)
  • 使用 DataReader 填充这些项目,而无需将所有查询结果加载到内存中。如果你知道一个事实(提前知道这一点非常重要) - 考虑使用 string.Intern - 仅当有很多重复项时! - 你应该测试看看它是如何工作的
  • 内存分析代码——你应该只看到字典的一个分配,以及查询中项目数量的字符串(int 是值类型——因此它没有作为对象分配在堆上,而是它位于字典中。

无论哪种方式,您都应该检查您是在 32 位还是 64 位上运行。 .Net 4.5 更喜欢 32 位。 (在任务管理器或项目属性中查看)

希望对您有所帮助,Ofir.

关于c# - 为什么我会收到 System.OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23348569/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com