在.Net框架中 2 GiB 是您可以为对象分配的最高内存。这个事实与平台( x64 或x86或...)独立。 我需要一个包含超过2 ^ 30个复数的大型列表(每个都是16个字节)。
注意:
与32位Windows操作系统一样,它有2GB的限制 运行64位托管时可以创建的对象的大小 应用程序在64位Windows操作系统上。
来自http://msdn.microsoft.com/en-us/library/ms241064%28VS.80%29.aspx
答案 0 :(得分:2)
然后你需要以其他方式封装它 - 创建你自己的可以处理足够数据的集合,并且可能会使用long
代替int
索引值等,通过在内部委托给较小的集合。我怀疑这不会很有趣,但我看不出你有很多其他的选择。
从根本上说,任何由单个阵列支持的东西都会遇到问题。
答案 1 :(得分:2)
让它变成锯齿状;例如Complex[][]
。如果需要,它可以是宽矩形锯齿状,只需对内部数组使用相同的大小即可。
另一种选择;使用大型列表的链表;这样做的好处是更容易扩展。
答案 2 :(得分:1)
我实现了一个在内部使用多个数组的包装类。
类似于以下内容:
void Main()
{
long count=3*1024*1024;
var arr=new LargeArray<Complex>(count,12);
for(long i=0;i<count;i++)
{
arr[i]=new Complex(i,-i);
}
for(long i=0;i<count;i++)
{
if(arr[i].R!=i)
throw new Exception("Fail"+i+" "+arr[i].R);
}
}
struct Complex
{
public double R,I;
public Complex(double r,double i)
{
R=r;
I=i;
}
}
class LargeArray<T>
{
private readonly int partBits;
private readonly long size;
private T[][] data;
public T this[long index]
{
get
{
if((ulong)index>=(ulong)size)
throw new IndexOutOfRangeException();
int part=(int)(index>>partBits);
int subIndex=(int)(index&((1<<partBits)-1));
return data[part][subIndex];
}
set
{
if((ulong)index>=(ulong)size)
throw new ArgumentOutOfRangeException();
int part=(int)(index>>partBits);
int subIndex=((int)index&((1<<partBits)-1));
data[part][subIndex]=value;
}
}
public LargeArray(long size,int partBits)
{
this.size=size;
this.partBits=partBits;
int partSize=1<<partBits;
int partCount=(int)(((size-1)>>partBits)+1);
data=new T[partCount][];
for(int i=0;i<partCount;i++)
data[i]=new T[partSize];
}
}
如果使用64位进程,则超出2GB。我尝试了5GB,除了交换我的程序停止工作。
答案 3 :(得分:1)
在.NET 4.5中,似乎数组实际上可能更大2 GB。对元素数量的硬性限制,而不是大小。 http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx
谈论新标志和数组的新限制。