C# 数组中的Outofmemory异常

C# 数组中的Outofmemory异常,c#,arrays,out-of-memory,C#,Arrays,Out Of Memory,我想创建一个大小为10^9个元素的数组,其中每个元素都可以是相同大小的整数。我总是在初始化行得到一个OutOfMemoryException。我怎样才能做到这一点 如果不可能,请建议其他策略 阵列在.net 4.0或更早版本中被限制为2GB,即使在64位进程中也是如此。因此,对于十亿个元素,支持的最大元素大小是两个字节,而int是四个字节。所以这是行不通的 如果您想拥有一个更大的集合,您需要自己编写,并由多个阵列支持 在.net 4.5中,可以避免此限制,有关详细信息,请参见Jon Skeet的

我想创建一个大小为10^9个元素的数组,其中每个元素都可以是相同大小的整数。我总是在初始化行得到一个OutOfMemoryException。我怎样才能做到这一点


如果不可能,请建议其他策略

阵列在.net 4.0或更早版本中被限制为2GB,即使在64位进程中也是如此。因此,对于十亿个元素,支持的最大元素大小是两个字节,而int是四个字节。所以这是行不通的

如果您想拥有一个更大的集合,您需要自己编写,并由多个阵列支持


在.net 4.5中,可以避免此限制,有关详细信息,请参见Jon Skeet的回答。

在.net 4.0或更早版本中,即使在64位进程中,阵列也被限制为2GB。因此,对于十亿个元素,支持的最大元素大小是两个字节,而int是四个字节。所以这是行不通的

如果您想拥有一个更大的集合,您需要自己编写,并由多个阵列支持

在.net 4.5中,可以避免此限制,有关详细信息,请参阅Jon Skeet的答案。

假设元素类型是int,如果使用64位CLR,则可以使用.net 4.5

您需要使用配置设置。默认情况下,此选项未启用

如果您使用的是较旧的CLR,或者您使用的是32位计算机,那么您就不走运了。当然,如果您在一台64位计算机上,但只是一个旧版本的CLR,您可以将一个大数组封装到一个单独的对象中,该对象包含一个较小数组的列表。。。您甚至可以通过这种方式实现IList,这样大多数代码就不需要知道您实际上没有使用单个数组

如注释中所述,您仍然只能创建包含231个元素的数组;但是您对109的要求在这个范围内。

假设您的元素类型是int,如果您使用的是64位CLR,那么您可以使用.NET 4.5来实现这一点

您需要使用配置设置。默认情况下,此选项未启用

如果您使用的是较旧的CLR,或者您使用的是32位计算机,那么您就不走运了。当然,如果您在一台64位计算机上,但只是一个旧版本的CLR,您可以将一个大数组封装到一个单独的对象中,该对象包含一个较小数组的列表。。。您甚至可以通过这种方式实现IList,这样大多数代码就不需要知道您实际上没有使用单个数组


如注释中所述,您仍然只能创建包含231个元素的数组;但是您对109的要求正好在这个范围内。

我认为您不应该将所有这些数据加载到内存中,将其存储在文件中的某个位置,并创建一个可以用作数组的类,但实际上可以从文件中读写数据

这是一般的想法,当然不会像现在这样工作,另外,在编写int值和其他一些东西之前,必须将int值转换为byte[]数组

public class FileArray
{
   Stream s;

   public this[int index]
   {
      get { s.Position = index * 4; return s.Read(); }
      set { s.Position = index * 4; s.Write(value); }
   }
}

这样的话,你会有一个像数组一样工作的东西,但是数据会存储在你的硬盘上

我认为你不应该将所有这些数据加载到内存中,存储在文件的某个地方,然后创建一个类,它可以像数组一样工作,但实际上从文件中读取和写入数据

这是一般的想法,当然不会像现在这样工作,另外,在编写int值和其他一些东西之前,必须将int值转换为byte[]数组

public class FileArray
{
   Stream s;

   public this[int index]
   {
      get { s.Position = index * 4; return s.Read(); }
      set { s.Position = index * 4; s.Write(value); }
   }
}


这样,您将拥有类似阵列的功能,但数据将存储在硬盘上

请与我们共享您的代码。声明阵列很简单。int[]数组=新的int[size];你得到运行时异常?10亿个int元素?!=>堆上的4Gb。其中每个元素可以是相同大小的整数..:这是一个数组。。不是数组列表或元组。我的意思是,我的数组不允许有重复的元素,所以如果它的大小是10^9个元素,那么它需要存储每个元素范围为10^9的元素。请与我们共享您的代码。声明数组很简单。int[]数组=新的int[size];你得到运行时异常?10亿个int元素?!=>堆上的4Gb。其中每个元素可以是相同大小的整数..:这是一个数组。。不是数组列表或元组。我的意思是,我的数组不允许重复元素,所以如果它的大小是10^9个元素,那么它需要存储每个元素范围为10^9的元素。有趣的是,我不知道.net 4.5允许这样做。在32位进程中,即使使用多个数组,他也不走运。4GB根本不适合这个地址空间。因此他需要将部分数据保留在其他地方。请注意,即使启用此功能,无论大小,最多也只能有大约2^31个可寻址元素。@MatthewWatson:是的,但这在OP要求的10^9范围内。无论如何都会对其进行编辑。很有趣,不知道.NET4.5允许这样做。在32位进程中,即使使用多个数组,他也不走运。4GB根本不适合这个地址
空间因此,他需要将部分数据保留在其他位置。请注意,即使启用此功能,无论大小,最多也将被限制为大约2^31个可寻址元素。@MatthewWatson:是的,但这在OP要求的10^9范围内。无论如何都将对其进行编辑。您确定数组在64位中限制为2GB吗?您有任何参考资料吗?@daryal但它适用于.NET 2.0默认情况下,在64位Windows操作系统上运行64位托管应用程序时,您可以创建不超过2 GB的对象。但是,在.NETFramework4.5中,可以增加此限制。有关更多信息,请参阅元素。@SonerGönül正如您所述,这是32位的;我不确定64位是否有限制。@CodesInChaos那么我认为您需要更改答案。您确定64位阵列限制为2GB吗?您有任何参考资料吗?@daryal但它适用于.NET 2.0默认情况下,在64位Windows操作系统上运行64位托管应用程序时,您可以创建不超过2 GB的对象。但是,在.NETFramework4.5中,可以增加此限制。有关更多信息,请参阅元素。@SonerGönül正如您所述,这是32位的;我不确定64位代码是否有限制。@CodesInChaos那么我认为您需要更改答案。完成!这就是我处理这个问题的方法,顺便说一句,这是伪代码,只是为了更好地解释ideaDone!这就是我处理这个问题的方法,顺便说一句,这是伪代码,只是为了更好地解释这个想法