16

如果有机会重写,我会,但无论如何,代码是这样的:

List<string> foobar;

然后我们在 foobar 中添加一堆字符串。

在 count=16777216 时,我们达到了内存不足的限制。

我的理解是每个字符串的大小都不同。确实看数据(不是我的数据),大多数是 2 或 3 个字符。

c# 中列表中数据的最大限制是多少?表示最大限制为:

理论上,当前 List 实现中可以存储的最大元素数是 Int32.MaxValue - 刚刚超过 20 亿。

然而:

在当前 Microsoft 的 CLR 实现中,最大对象大小限制为 2GB。(其他实现,例如 Mono,可能没有这个限制。)

在我的示例中,我有 1600 万个结果 * 几个字节?任务管理器显示正在使用的演出,但我有 8 演出的 RAM。

16777216 (2^24) 似乎是一个相当具体的值 - 可疑地像一个限制,但我在任何地方都找不到任何文档来 a) 备份它或 b) 找到解决方法?

任何帮助,将不胜感激。


一些代码:

List<string> returnList = new List<string>();
SqlDataReader dr; //  executes a read on a database, have removed that part as that bit works fine

  if (dr.HasRows)
  {
      while (dr.Read())
      {
          returnList.Add(dr.GetString(0).Trim());
      }
  }

这是简化的形式,我现在对 OOM 异常进行了一些尝试/捕获,但这是让我感到悲伤的实际代码。

4

3 回答 3

12

如果您尝试在 64 位环境中使用非常大的列表,则需要在应用程序配置中启用大对象。

http://msdn.microsoft.com/en-us/library/hh285054.aspx

OOM 可能是由于 Lists/ArrayLists 分配内存的方式,我相信每次达到它们的边界时,它们都会尝试将大小加倍。该列表不能从 2^24 翻倍。理论上,您可以通过预先指定大小来最大化列表大小。(即 2GB)

于 2012-11-22T23:24:37.507 回答
1

我已经发布了我在这里所做的事情,值得一试。同样的步骤是:

  1. 在使用存储过程的数据的每个迭代查询部分
  2. 转移它们
  3. 移动到下一部分

    List<string> returnList;
    int index = 0;
    SqlCommand cmd = new SqlCommand("ExampleStoredProc", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    while (true)
    {
        cmd.Parameters.Add(
            new SqlParameter("@index", index));
        SqlDataReader dr = cmd.ExecuteReader();
        if (dr.HasRows)
        {
            returnList = new List<string>();
            returnList.Add(dr.GetString(0).Trim());
            //transfer data here
        }
        else
        {
            break;
        }
        index++;
    }
    

并且存储的过程应该是这样的:

CREATE PROCEDURE ExampleStoredProc
    @index INT
AS
BEGIN
    SELECT * 
    FROM  veryBigTable
    WHERE Id >= (@index *1000) AND Id < ((@index + 1) * 1000)
END
GO

不管你有多少记录,我肯定会工作,只是你拥有的数据越多,完成的时间就越长。

于 2012-11-22T23:30:49.593 回答
1

如果当您手动设置正确的列表大小时它甚至小于 2^24,那么这可能是在正确的轨道上。与其达到 1600 万,然后尝试将列表的大小翻倍,不如让列表变得非常大,并且更早地耗尽内存。

这就解释了为什么你得到一个整数 - 它达到了 2^24 然后试图增加大小,这导致它使用了太多的内存。

在我看来,这是某种“自然”对象大小限制,而不是列表实现中的限制。

于 2012-11-23T00:16:58.307 回答