Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 扩展使用数组以防止内存不足异常的简单方法是什么?_C#_Arrays_Out Of Memory - Fatal编程技术网

C# 扩展使用数组以防止内存不足异常的简单方法是什么?

C# 扩展使用数组以防止内存不足异常的简单方法是什么?,c#,arrays,out-of-memory,C#,Arrays,Out Of Memory,但我到目前为止的经验是,当我定义大于100的新数组时,它将从内存中消失 我的想法是,初始化四个大小为100的新数组。并使用四个新阵列,从不同的初始计数器开始,如下所示: tempData[30][40, 400, 400, 5] float[][,]tempData0=新的float[30][,]; 浮点[][,]tempData1=新浮点[30][,]; 浮点[][,]tempData2=新浮点[30][,]; 浮点[][,]tempData3=新浮点[30][,]; 私有void Init

但我到目前为止的经验是,当我定义大于100的新数组时,它将从内存中消失

我的想法是,初始化四个大小为100的新数组。并使用四个新阵列,从不同的初始计数器开始,如下所示:

tempData[30][40, 400, 400, 5]
float[][,]tempData0=新的float[30][,];
浮点[][,]tempData1=新浮点[30][,];
浮点[][,]tempData2=新浮点[30][,];
浮点[][,]tempData3=新浮点[30][,];
私有void InitTempData()
{
const int FocusSize=100;
尝试
{
对于(int i=0;i<30;i++)
{
tempData0[i]=新浮点[40,聚焦,聚焦,5];
tempData1[i]=新浮点[40,聚焦,聚焦,5];
tempData2[i]=新浮点[40,聚焦,聚焦,5];
tempData3[i]=新浮点[40,聚焦,聚焦,5];
}
}
捕获(OutOfMemoryException ex)
{
MessageBox.Show(例如Message);
}
}
//使用不同初始计数器的tempData0、tempData1、tempData2和tempData3
对于(int i=0;i<30;i++)
{
对于(int x=0;x

我的上述想法是正确的做法吗?或者是否有其他扩展数组使用的选项

这是一个相当大的数组:

float[][, , ,] tempData0 = new float[30][, , ,];
float[][, , ,] tempData1 = new float[30][, , ,];
float[][, , ,] tempData2 = new float[30][, , ,];
float[][, , ,] tempData3 = new float[30][, , ,];

private void InitTempData()
{
    const int FocusSize = 100;
    try
    {
        for (int i = 0; i < 30; i++)
        {
            tempData0[i] = new float[40, FocusSize, FocusSize, 5];
            tempData1[i] = new float[40, FocusSize, FocusSize, 5];
            tempData2[i] = new float[40, FocusSize, FocusSize, 5];
            tempData3[i] = new float[40, FocusSize, FocusSize, 5];
        }
    }
    catch (OutOfMemoryException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

//Use the tempData0, tempData1, tempData2, and tempData3 with different initial counter
for (int i = 0; i < 30; i++)
{
    for (int x = 0; x < FocusSize; x++)
    {
        for (int z = 0; z < FocusSize; z++)
        {
            //Use tempData0 here
        }
    }
}

for (int i = 0; i < 30; i++)
{
    for (int x = FocusSize; x < FocusSize * 2; x++)
    {
        for (int z = FocusSize; z < FocusSize * 2; z++)
        {
            //Use tempData1 here
        }
    }
}

for (int i = 0; i < 30; i++)
{
    for (int x = FocusSize * 2; x < FocusSize * 3; x++)
    {
        for (int z = FocusSize * 2; z < FocusSize * 3; z++)
        {
            //Use tempData2 here
        }
    }
}
假设您有那么多的空闲内存,并且正在运行64位进程(大于2/3GB需要),那么您可能遇到了麻烦,因为阵列在内存中是作为连续块布置的

在上面使用[30][40400400,5]的示例中,您要求CLR查找30个128Mb内存块

见:

您可以尝试创建引用较小数组的列表,或者简单地将其声明为“锯齿”数组,以避免连续内存问题(代价是取消对数组数组的引用时性能最差)


i、 浮点数[30][40][400][400][5]

它必须是数组吗

我将创建一个带有getter和setter的类。然后,内部存储器可以使用更小的阵列

30 * 40 * 400 * 400 * 5 * (4 bytes) ~= 3.6GB total
公共类五维数据{
private const int BucketSize=16384;//将对象排除在LOH之外
私人T[][]\U桶;
私有整数x,y,z,v;
公共五维数据(整数x,整数y,整数z,整数u,整数v){
if(x<0)
抛出新ArgumentOutOfRangeException(“x”);
if(y<0)
抛出新ArgumentOutOfRangeException(“y”);
if(z<0)
抛出新ArgumentOutOfRangeException(“z”);
if(u<0)
抛出新ArgumentOutOfRangeException(“u”);
if(v<0)
抛出新ArgumentOutOfRangeException(“v”);
_x=x;
_y=y;
_z=z;
_u=u;
_v=v;
长总尺寸=((长)x)*y*z*u*v;
整数totalbucket=(整数)(totalSize/BucketSize)+1;
_bucket=新的T[totalbucket][];
对于(int ii=0;iix)
抛出新ArgumentOutOfRangeException(“x”);
如果(y<0 | | y>|y)
抛出新ArgumentOutOfRangeException(“y”);
如果(z<0 | | z>z)
抛出新ArgumentOutOfRangeException(“z”);
如果(u<0 | | u>_)
抛出新ArgumentOutOfRangeException(“u”);
如果(v<0 | | v>|v)
抛出新ArgumentOutOfRangeException(“v”);
长索引=(长)x*_y*_z*_*_v+
(长)y*_z*_*_v+
(长)z*\u*\u v+
(长)u*\u v+
(长)v;
收益指数;
}
}            

如果您使用的是Windows 32位(86x),则在添加新元素之前,必须检查内存大小

public class FiveDimensionalData<T> {
    private const int BucketSize = 16384; // keep object out of LOH
    private T[][] _buckets;
    private int _x, _y, _z, _u, _v;

    public FiveDimensionalData(int x, int y, int z, int u, int v) {
        if (x < 0)
            throw new ArgumentOutOfRangeException("x");
        if (y < 0)
            throw new ArgumentOutOfRangeException("y");
        if (z < 0)
            throw new ArgumentOutOfRangeException("z");
        if (u < 0)
            throw new ArgumentOutOfRangeException("u");
        if (v < 0)
            throw new ArgumentOutOfRangeException("v");

        _x = x;
        _y = y;
        _z = z;
        _u = u;
        _v = v;

        long totalSize = ((long)x)*y*z*u*v;

        int totalBuckets = (int)(totalSize / BucketSize) + 1;
        _buckets = new T[totalBuckets][];

        for (int ii = 0; ii < totalBuckets; ++ii)
            _buckets[ii] = new T[BucketSize];
    }

    public T Get(int x, int y, int z, int u, int v) {
        long bucketIndex = Index(x, y, z, u, v); 

        int bucket = (int)(bucketIndex / BucketSize);
        int positionInBucket = (int)(bucketIndex % BucketSize);

        return _buckets[bucket][positionInBucket];
    }

    public void Set(int x, int y, int z, int u, int v, T value) {
        long bucketIndex = Index(x, y, z, u, v); 

        int bucket = (int)(bucketIndex / BucketSize);
        int positionInBucket = (int)(bucketIndex % BucketSize);

        _buckets[bucket][positionInBucket] = value;
    }

    private long Index(int x, int y, int z, int u, int v) {
        if (x < 0 || x > _x)
            throw new ArgumentOutOfRangeException("x");
        if (y < 0 || y > _y)
            throw new ArgumentOutOfRangeException("y");
        if (z < 0 || z > _z)
            throw new ArgumentOutOfRangeException("z");
        if (u < 0 || u > _u)
            throw new ArgumentOutOfRangeException("u");
        if (v < 0 || v > _v)
            throw new ArgumentOutOfRangeException("v");

        long index = (long)x * _y * _z * _u * _v + 
                     (long)y * _z * _u * _v +
                     (long)z * _u * _v +
                     (long)u * _v +
                     (long)v;
        return index;
    }
}            
获取当前进程并使用:
Process proc=Process.GetCurrentProcess(); 私有存储器程序64

如果我没有弄错的话,您声明这些数组的方式将使您得到锯齿状数组的数组。如果您确定这正是您想要做的,也许您应该尝试使用x64目标构建?它在.net4.0上运行。我刚刚发现,如果我在.net4.5上这样做,它可以使用config-like设置为true。每个多维数组(即
float[40400400,5]
)需要128 MB的连续内存。总而言之,您为100个阵列分配的内存略多于12.8GB。您的计算机上有那么多可用内存吗?您可以增加分页文件的大小,这可能允许您分配内存。但是你的表现会受到影响。您必须找到一些方法来减少内存需求或获得更多RAM。没有“魔法”能让你把12.8GB的东西放进8GB的袋子里。我能知道吗
public class FiveDimensionalData<T> {
    private const int BucketSize = 16384; // keep object out of LOH
    private T[][] _buckets;
    private int _x, _y, _z, _u, _v;

    public FiveDimensionalData(int x, int y, int z, int u, int v) {
        if (x < 0)
            throw new ArgumentOutOfRangeException("x");
        if (y < 0)
            throw new ArgumentOutOfRangeException("y");
        if (z < 0)
            throw new ArgumentOutOfRangeException("z");
        if (u < 0)
            throw new ArgumentOutOfRangeException("u");
        if (v < 0)
            throw new ArgumentOutOfRangeException("v");

        _x = x;
        _y = y;
        _z = z;
        _u = u;
        _v = v;

        long totalSize = ((long)x)*y*z*u*v;

        int totalBuckets = (int)(totalSize / BucketSize) + 1;
        _buckets = new T[totalBuckets][];

        for (int ii = 0; ii < totalBuckets; ++ii)
            _buckets[ii] = new T[BucketSize];
    }

    public T Get(int x, int y, int z, int u, int v) {
        long bucketIndex = Index(x, y, z, u, v); 

        int bucket = (int)(bucketIndex / BucketSize);
        int positionInBucket = (int)(bucketIndex % BucketSize);

        return _buckets[bucket][positionInBucket];
    }

    public void Set(int x, int y, int z, int u, int v, T value) {
        long bucketIndex = Index(x, y, z, u, v); 

        int bucket = (int)(bucketIndex / BucketSize);
        int positionInBucket = (int)(bucketIndex % BucketSize);

        _buckets[bucket][positionInBucket] = value;
    }

    private long Index(int x, int y, int z, int u, int v) {
        if (x < 0 || x > _x)
            throw new ArgumentOutOfRangeException("x");
        if (y < 0 || y > _y)
            throw new ArgumentOutOfRangeException("y");
        if (z < 0 || z > _z)
            throw new ArgumentOutOfRangeException("z");
        if (u < 0 || u > _u)
            throw new ArgumentOutOfRangeException("u");
        if (v < 0 || v > _v)
            throw new ArgumentOutOfRangeException("v");

        long index = (long)x * _y * _z * _u * _v + 
                     (long)y * _z * _u * _v +
                     (long)z * _u * _v +
                     (long)u * _v +
                     (long)v;
        return index;
    }
}            
// Here you have to check that the current used memory in your process; this shall not exceed more than 2 GB;
// If you are using  /LARGEADDRESSAWARE than not exceed 4 GB
If (MemoryHelper.CanAllocateObject())
{
 // here add a new elements
}