C# 在循环中创建数组会引发OutOfMemoryException
我正在用C语言开发一个用来处理图像的软件。我有很多图像(超过11000个),当我在几分钟后执行我的程序时,我有一个“OutOfMemoryException” 这是我的代码:C# 在循环中创建数组会引发OutOfMemoryException,c#,C#,我正在用C语言开发一个用来处理图像的软件。我有很多图像(超过11000个),当我在几分钟后执行我的程序时,我有一个“OutOfMemoryException” 这是我的代码: private void GenerateImages() { try { Parallel.ForEach(listImagesStart, startImg => { bool docontinue = true; t
private void GenerateImages()
{
try
{
Parallel.ForEach(listImagesStart, startImg =>
{
bool docontinue = true;
try
{
startImg.LoadImage(_baseFileResults);
}
catch
{
docontinue = false;
}
if (docontinue)
{
//Save image as file
startImg.Save();
// Do rotate
MyImg lastRotate = baseImg;
MyImg imgtmp;
String[] tabRotate = new String[3] { "_90", "_180", "_270"};
foreach (String rotate in tabRotate)
{
imgtmp = new GenImg(baseImg.FileName + rotate + baseImg.FileExtension);
imgtmp.LoadImage(lastRotate);
imgtmp.Rotate90();
imgtmp.Save();
lastRotate = imgtmp;
}
startImg.Dispose();
imgtmp.Dispose();
}
});
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
#if DEBUG
MessageBox.Show(e.StackTrace, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
#endif
}
}
和MyImg:
class myImg
{
public Byte[] Matrix;
public int Height;
public int Width;
public void LoadImage(String filePath)
{
// create new Matrix/Heigth/Width from file
}
public void LoadImage(myImg img)
{
Matrix = new Byte[img.Matrix.Length];
Array.Copy(img.Matrix, Matrix, img.Matrix.Length);
Height = img.Height;
Width = img.Width;
}
public void Rotate90()
{
// Save before
int tmpWidth = Height;
int tmpHeight = Width;
Byte[] tmpMatrix = new Byte[Matrix.Length];
for (int r = 0; r < tmpHeight; r++)
{
for (int c = 0; c < tmpWidth; c++)
{
int prevR = Height - c - 1;
int prevC = r;
tmpMatrix[c + r * tmpWidth] = Matrix[prevC + prevR * Width];
}
}
// Copy new image
Array.Copy(tmpMatrix, Matrix, Matrix.Length);
Width = tmpWidth;
Height = tmpHeight;
}
public void Dispose()
{
SavePath = null;
Matrix = null;
Points = null;
Width = 0;
Height = 0;
GC.Collect();
}
}
类myImg
{
公共字节[]矩阵;
公众内部高度;
公共整数宽度;
公共void LoadImage(字符串文件路径)
{
//从文件创建新矩阵/高度/宽度
}
公共void LoadImage(myImg img)
{
矩阵=新字节[img.Matrix.Length];
复制(img.Matrix,Matrix,img.Matrix.Length);
高度=最小高度;
宽度=最小宽度;
}
公共空间90()
{
//提前保存
int tmpWidth=高度;
int tmpHeight=宽度;
字节[]tmpMatrix=新字节[Matrix.Length];
对于(int r=0;r
SystemOutOfMemoryException发生在指令
新字节[长度]
处。我想这是因为我创建了太多的数组,但我不知道该怎么办。主要问题是listmagessstart
保留了每个startImg
项的引用。这将防止GC释放由myImg.LoadImage
(使用数组矩阵)分配的内存
一个快速解决方案:您可以将矩阵设置为null以回收内存
public void UnLoadImage()
{
Matrix = null ; // this will allow GC to recycle memory used by Matrix
}
然后(我删除了无用的docontinue变量):
在foreach循环中,调用imgtmp.LoadImage和Rotate90都可以找到内存。这是处理11000张图像的循环吗?此外,您不会提及每个图像有多大。在离开此循环之前,您不会调用dispose。这个foreach循环在一个并行的for中。您应该重新考虑如何调用Dispose。@DaveS我正在并行处理11000个图像。Foreach,列表为
listImagesStart
。图像为700x700像素。如果docontinue为false,我将代码修改为调用Dispose
。(我正在等待结果)是否可以调用我的Dispose
而不是UnLoadImage
?我的Dispose执行Matrix=null
您可以将UnloadImage重命名为Dispose(),并实现IDisposable
try
{
startImg.LoadImage(_baseFileResults);
//Save image as file
startImg.Save();
// Do rotate
MyImg lastRotate = baseImg;
MyImg imgtmp;
String[] tabRotate = new String[3] { "_90", "_180", "_270"};
foreach (String rotate in tabRotate)
{
imgtmp = new GenImg(baseImg.FileName + rotate + baseImg.FileExtension);
imgtmp.LoadImage(lastRotate);
imgtmp.Rotate90();
imgtmp.Save();
lastRotate = imgtmp;
}
startImg.Dispose();
imgtmp.Dispose();
}
catch
{
}
finally
{
startImg.Unload(); // Here is the trick
}