【发布时间】:2017-10-13 13:23:10
【问题描述】:
我正在将文件读入一个数组;这是相关代码;为每个文件创建一个新的 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[编辑:
“第一次运行这个”是一个错误的选择,我的意思是当我启动程序并打开一个文件时很好,当我尝试在不退出程序的情况下打开另一个文件时出现问题。当我打开第二个文件时,我将 DiskReader 设置为一个新实例,这意味着 fileData 数组也是一个新实例。我希望这能让它更清楚。]
fileData = new Byte[NumBytes];
它运行并抛出异常没有明显的模式。
我认为这无关紧要,但虽然最大文件大小设置为 300 MB,但我用来测试的文件大小在 49 到 64 MB 之间。
关于这里出了什么问题以及如何纠正它的任何建议?
【问题讨论】:
-
“我第一次运行这个”是什么意思?它是一个单独的程序吗?在您再次调用此代码之前它是否完全关闭并完全重新启动?因为异常清楚地表明你的内存已满。您可能会将旧数组保存在内存中。它看起来与文件流和磁盘无关。
-
您打开了多少个文件,或者您同时启动了多少个程序实例? System.OutOfMemoryException rly 表示你的内存不足。这部分代码没有问题。发布你留下的内容
-
如果您在短时间内创建和删除大型数组,它们可能没有足够快地被垃圾收集 - 强制垃圾收集可以解决这个问题。以下是一些给出不同观点的链接:social.msdn.microsoft.com/Forums/vstudio/en-US/…stackoverflow.com/questions/14724107/…stackoverflow.com/questions/4688348/…
-
如果你这样做会痛,那么不要那样做。将大文件读入数组是一种糟糕的做法。流式传输大文件。
-
如果您遇到内存问题,请使用内存分析器找出问题的原因,而不是猜测。
标签: c# arrays out-of-memory