C#system.outofmemoryexception

时间:2010-10-28 10:58:39

标签: c#

我必须处理一个有两列和80000行的表。我需要在两个列之间对该表进行比较,这会在运行时导致system.out内存异常。

我会将第一个记录值与79,999 记录的其余部分进行比较,即(1,1),(1,2), ......(1,79999),(2,1),(2,2),......(2,79999)......(3,1),(3,2), ....(3,79999)...

如何处理这种情况

提前致谢

这是我的代码:

SqlCommand cmd = new SqlCommand("select (g.gene),n.goterm,(n.gene) from genematrix g  join genematrix n on n.goterm=g.goterm where g.id<n.id", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);

表名GeneMatrix:

GoTerm    Gene

1a       gene1
2b       gene1
1a       gene2
2b       gene3

等到80000记录............

上面是表结构,我将从中比较第一个基因记录和所有其他基因记录,然后进入第二个基因记录并开始将其与所有其他记录进行比较......直到最后一个基因。

当我将gene1与gene2进行比较以获得常见的术语时,结果就像

gene1 gene2 1a
gene1 gene3 2b

我的上面的查询正确地返回输出,但问题是..a system.outofmemoryexception被显示,我无法让查询完全运行直到结束。

6 个答案:

答案 0 :(得分:0)

您应该将比较代码拆分为较小的部分,例如一次1000条记录,对这些记录进行比较,然后得到接下来的1000条记录。

您遇到的问题很可能是由于您一次抓取大量记录。

答案 1 :(得分:0)

您没有指定要比较的内容,或者如果找到匹配项,您应该做什么。

无论如何,我建议您使用the Parallel LINQ extensions。他们认真对待这样的工作,并且有很多聪明才智可以选择最好的工作方法。

答案 2 :(得分:0)

使用 DataReader 代替数据集,它将提高应用程序性能并降低系统开销。这是由于一次一行存储在内存中。在创建Command对象的实例后,通过调用Command.ExecuteReader来创建DataReader。看http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx

答案 3 :(得分:0)

您不应该使用交叉连接。最好将你的表加载到主内存中,如下所示:

SqlCommand cmd 
= new SqlCommand("select g.goterm,g.gene from genematrix g ", con);
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    DataSet ds = new DataSet();
    da.Fill(ds);

然后使用Dictionary进行比较。这里有一些“空气代码”(未经测试,未经编译,只是出于我的想法):

var d = new Dictionary<string, List<string>();
for each(var row in ds.Rows)
{
    string key = (string)row["goterm"];
    if(!d.ContainsKey(key))
        d.Add(key, new List<string>());
     d[key].Add((string)row["gene"]);
}

for each(var k in d.Keys)
{
     Console.Write(k + ": ");
     for each(var gene in d[k])
          Console.Write(gene + " ");
     Console.WriteLine();
}

(ALAS,如果这不仅仅是开箱即用,它应该会让你大致了解如何解决它。)

答案 4 :(得分:0)

检查您是否正在构建64位进程,而不是32位进程,这是Visual Studio的默认编译模式。为此,右键单击您的项目,属性 - &gt;构建 - &gt;平台目标:x64。与任何32位进程一样,以32位编译的Visual Studio应用程序的虚拟内存限制为2GB。

64位进程没有此限制,因为它们使用64位指针,因此它们的理论最大地址空间为16艾字节(2 ^ 64)。实际上,Windows x64将进程的虚拟内存限制为8TB。然后,内存限制问题的解决方案是以64位编译。

但是,默认情况下,Visual Studio中对象的大小仍限制为2GB。您将能够创建多个组合大小将大于2GB的阵列,但默认情况下不能创建大于2GB的阵列。希望如果您仍然想要创建大于2GB的数组,可以通过向app.config文件添加以下代码来实现:

<configuration>
  <runtime>
    <gcAllowVeryLargeObjects enabled="true" />
  </runtime>
</configuration>

答案 5 :(得分:0)

我认为你没有正确地描述你的问题。您从一个包含2列的表开始,但您的代码段会加载包含3列的联接。

请显示导致OutOfMemory异常的行。

理论1。 运行计数查询:从n.goterm = g.goterm中的genematrix g join genematrix n中选择count(g.gene),其中g.id

理论2。 如果加载记录是问题,那么我认为你在代码中构建80000 * 80000数组。即使您的条目只有一个字节,80000 * 80000b = 6400000000b = 5.9GB,这更多.Net'单个对象2GB'限制。