抛出了类型'System.OutOfMemoryException'的异常.C#使用IDataReader时

DA_*_*rog 7 c# sql exception datareader using-statement

我有一个应用程序,我必须从DB获取大量数据.由于它未能获得所有这些行(它接近2,000,000行...),我在中断时将其剪切,并且每次执行sql查询时每次只获得200,000行.

我使用DataTable输入所有数据(意思是 - 所有2,000,000行应该在那里).

前几次运行很好.然后它以OutOfMemoryException失败.

我的代码如下:

private static void RunQueryAndAddToDT(string sql, string lastRowID, SqlConnection conn, DataTable dt, int prevRowCount)
    {
        if (string.IsNullOrEmpty(sql))
        {
            sql = generateSqlQuery(lastRowID);
        }

        if (conn.State == ConnectionState.Closed)
        {
            conn.Open();
        }

        using (IDbCommand cmd2 = conn.CreateCommand())
        {
            cmd2.CommandType = CommandType.Text;
            cmd2.CommandText = sql;
            cmd2.CommandTimeout = 0;

            using (IDataReader reader = cmd2.ExecuteReader())
            {
                while (reader.Read())
                {
                    DataRow row = dt.NewRow();
                    row["RowID"] = reader["RowID"].ToString();
                    row["MyCol"] = reader["MyCol"].ToString();
                    ... //In one of these rows it returns the exception.

                    dt.Rows.Add(row);
                }
            }
        }

        if (conn != null)
        {
            conn.Close();
        }

        if (dt.Rows.Count > prevRowCount)
        {
            lastRowID = dt.Rows[dt.Rows.Count - 1]["RowID"].ToString();
            sql = string.Empty;
            RunQueryAndAddToDT(sql, lastRowID, conn, dt, dt.Rows.Count);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在我看来好像读者一直在收集行,这就是为什么它只在第三轮或第二轮抛出异常.

不应该使用清理内存吗?什么可以解决我的问题?

注意:我应该解释一下 - 我别无选择,只能将所有这些行都放到数据表中,因为我稍后会对它们进行一些操作,并且行的顺序很重要,我不能拆分它,因为有时我有获取某些行的数据并将其设置为一行,依此类推,等等,所以我无法放弃.

谢谢.

小智 12

检查您是否正在构建64位进程,而不是32位进程,这是Visual Studio的默认编译模式.为此,右键单击您的项目,属性 - >构建 - >平台目标: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>
Run Code Online (Sandbox Code Playgroud)


And*_*rew 4

我认为只是你耗尽了内存,因为你的数据表由于你不断添加的所有行而变得如此之大。

在这种情况下,您可能想尝试不同的模式。

您是否可以简单地生成这些行,因为它们在到达时可供使用,而不是在列表(或 DataTable)中缓冲行?