内存不足异常。创建一个大矩阵。

3

我有一个矩阵 [3,15000]。我需要计算原始矩阵的协方差矩阵,然后找到它的特征值。

以下是我的代码的一部分:

double[,] covarianceMatrix = new double[numberOfObjects,numberOfObjects];
for (int n=0; n<numberOfObjects;n++)
    {
    for (int m=0;m<numberOfObjects;m++)
    {
        double sum = 0;
        for (int k=0; k<TimeAndRepeats[i,1]; k++)
        {
            sum += originalMatrix[k,n]*originalMatrix[k,m];
        }
    covarianceMatrix[n,m] = sum/TimeAndRepeats[i,1];
    }
}
alglib.smatrixevd(covarianceMatrix,numberOfObjects,1,true,out eigenValues, out eigenVectors);

这里的NumberOfObjects大约有15000个。

当我计算较少数量的对象时,一切正常,但对于所有数据,我都会遇到异常。

有可能解决这个问题吗?

我使用的操作系统是macOS,x64位。

我的开发环境是MonoDevelop。

3个回答

4
double[,] covarianceMatrix = new double[numberOfObjects,numberOfObjects];

你说你的矩阵是[3, 15000],而numberOfObjects是15000。通过这行代码,你正在创建一个由double组成的[15000,15000]的矩阵。

15000 * 15000 = 225000000个double,每个占8个字节:1,800,000,000个字节或1.8GB

这可能就是为什么你会耗尽内存的原因。

编辑:

根据这个问题这个问题,C#中对象的大小不能大于2GB。1.8GB不包括引用数组项所需的任何额外开销,因此当考虑到所有内容时,1.8GB实际上可能大于2GB(没有调试信息无法确定,需要更多C#经验的人帮助解决)。如果您正在处理非常大的数组,则可以考虑使用这个解决方案,因为静态分配的数组可能会变得混乱。


我能否让我的程序使用更多的内存来避免这个异常? - user2080209
x64不支持每个进程寻址更多的内存吗?或者这只是Mac的问题...在Windows的x64上不会出现这种情况。 - Vivek
1
@Vivek x64 允许处理更大的整数值和内存地址(因为你使用的是 64 个 1 和 0,而不是 32 个)。但它并不会改变 C# 处理数据结构的最大尺寸。 - Justin Pearce

0

当你创建covarianceMatrix时,你正在创建一个15000*15000 = 225000000的对象

因此,你需要1800000000字节的内存。正是因为这个原因,你才会遇到OutOfMemoryException异常。


这是关于Monodevelop设置的问题吗? - user2080209
1800000000大约是1.7 GB,这意味着您必须有1.7 GB的可用RAM可以分配给您的程序(我不会深入细节,这里我简化了一下),所以我认为当您使用更强大的机器时,您将能够轻松进行此计算。 - Swift

0

异常名称告诉您问题的确切所在。您可以使用浮点数而不是双精度浮点数来二分所需内存的数量。另一个选择是创建一些类对象用于协方差矩阵,将数据保存在磁盘文件中,但您需要实现适当的机制来操作它,性能也会受到限制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接