创建新数组时的C#System.OutOfMemoryException

时间:2017-10-13 13:23:11

标签: c# arrays out-of-memory

我正在将文件读入数组;这是相关的代码;为每个文件创建一个新的DiskReader,并使用OpenFileDialog确定路径。

 class DiskReader{
// from variables section:
    long MAX_STREAM_SIZE = 300 * 1024 * 1024; //300 MB


    FileStream fs;
    public Byte[] fileData;

...

// Get file size, check it is within allowed size (MAX)STREAM_SIZE), start process including progress bar.

using (fs = File.OpenRead(path))
            {
                if (fs.Length < MAX_STREAM_SIZE)
                {
                    long NumBytes = (fs.Length < MAX_STREAM_SIZE ? fs.Length : MAX_STREAM_SIZE);
                    updateValues[0] = (NumBytes / 1024 / 1024).ToString("#,###.0");
                    result = LoadData(NumBytes);
                }
                else
                {
                    // Need for something to handle big files
                }

                if (result)
                {
                    mainForm.ShowProgress(true);
                    bw.RunWorkerAsync();
                }

            }

...

    bool LoadData(long NumBytes)
    {
        try
        {
            fileData = new Byte[NumBytes];
            fs.Read(fileData, 0, fileData.Length); 
            return true;
        }
        catch (Exception e)
        {
            return false;
        }
    }

我第一次运行它,它运行正常。我第二次运行它,有时它工作正常,大多数时候它抛出一个System.OutOfMemoryException

[编辑:

&#34;我第一次运行这个&#34;是一个糟糕的选择,我的意思是当我启动程序并打开文件很好,当我尝试打开一个不同的文件而不退出该程序时,我遇到了问题。当我打开第二个文件时,我将DiskReader设置为一个新实例,这意味着fileData数组也是一个新实例。我希望这更清楚。]

  fileData = new Byte[NumBytes]; 

没有明显的模式可以运行并抛出异常。

我认为它不相关,但是虽然最大文件大小设置为300 MB,但我用来测试它的文件介于49到64 MB之间。

有关此处出现问题以及如何纠正错误的建议吗?

3 个答案:

答案 0 :(得分:0)

如果仅在该行抛出异常,那么我的猜测是您在代码中的其他位置出现了问题,正如评论所示。阅读该异常的文档here,我敢打赌你在某个地方多次调用这个函数并且只是超过了内存中对象长度的限制,因为它似乎不是任何您发布的代码中的问题点。

答案 1 :(得分:0)

fs.Length属性需要评估整个流,因此无论如何都要读取文件。尝试做类似

的事情
    byte[] result;
    if (new FileInfo(path).Length < MAX_STREAM_SIZE)
    {
        result = File.ReadAllBytes(path);
    }

另外,根据您的需要,您可以避免使用字节数组并直接从文件流中读取数据。这应该具有更低的内存占用

答案 2 :(得分:0)

如果我很清楚你想做什么,我有这个建议:最好的选择是在开头分配一个定义的MAX大小的静态数组。然后保留该数组,只用另一个文件中的新数据填充它。这样你的记忆应该是绝对正常的。您只需将文件大小存储在单独的变量中,因为该数组的MAX大小始终相同。

这是具有自动内存管理的系统中的常用方法 - 当您在开始时分配常量内存并且在计算期间从不分配任何内容时,它会使程序更快,因为垃圾收集器不会运行多次。 / p>