在.Net框架中2 GiB是可以爲對象分配的最高內存。這個事實是來自平臺的獨立(x64或x86或...)。 我需要一個超過2^30複數(每個是16字節)的巨大列表。如何擁有一個巨大的列表?大於2 GiB?
注:
與32位Windows操作系統,有對 大小的物體運行的時候,你可以創建一個2GB的限制在64位的64位管理 應用Windows操作系統。
從http://msdn.microsoft.com/en-us/library/ms241064%28VS.80%29.aspx
在.Net框架中2 GiB是可以爲對象分配的最高內存。這個事實是來自平臺的獨立(x64或x86或...)。 我需要一個超過2^30複數(每個是16字節)的巨大列表。如何擁有一個巨大的列表?大於2 GiB?
注:
與32位Windows操作系統,有對 大小的物體運行的時候,你可以創建一個2GB的限制在64位的64位管理 應用Windows操作系統。
從http://msdn.microsoft.com/en-us/library/ms241064%28VS.80%29.aspx
我會實現一個內部使用多個數組的包裝類。
類似以下內容:
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試了一下,除了交換我的配置以停止工作。
小修正:修正了一些小問題後,最後一個塊可能會更小(4個元素,4,1個「塊」中的9個元素) – xanatos
@salman此代碼在2GB以上工作正常。在我的測試中,它處理得很好,分配了5 GB的內存。當然,我將它作爲64位進程運行。所以我不明白你的問題是什麼。但既然你確定你的程序是64位的,那也不是你的問題。所以我唯一能想到的是你使用了一個'Complex'類而不是'Complex'結構。 – CodesInChaos
@xanatos我知道。但這是一個小問題。如果你分配5GB的內存,你不會在乎1MB或多或少的。 – CodesInChaos
然後,你需要封裝,在一些其他的方式 - 建立自己的最愛,其可以處理足夠的數據,並可能會使用long
代替int
的索引值,等等,通過委託給內部較小的集合。我懷疑它不會很有趣,但我看不到你有很多其他選擇。
基本上,任何由單個陣列支持的東西都會遇到問題。
改爲鋸齒;例如Complex[][]
。如果您需要,它可以是大致矩形的鋸齒形,只需通過始終使用相同尺寸的內部陣列即可。
另一種選擇;使用大型列表的鏈接列表;這具有更容易擴展的優點。
在.NET 4.5中,看起來數組實際上可能大於2 GB。對元素數量有嚴格的限制,而不是大小。 http://msdn.microsoft.com/en-us/library/hh285054(v=vs.110).aspx
談論有關新標誌和陣列的新限制。
您需要一個可佔用17.18 GB RAM的對象?除非你有一些優秀的服務器,否則你可能需要考慮採取不同的方式來做到這一點。 – Ben
http://blogs.msdn.com/b/joshwil/archive/2005/08/10/450202.aspx – LukeH
@爲什麼?我在桌面上得到了更多...... –