Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.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# 在循环中创建数组会引发OutOfMemoryException_C# - Fatal编程技术网

C# 在循环中创建数组会引发OutOfMemoryException

C# 在循环中创建数组会引发OutOfMemoryException,c#,C#,我正在用C语言开发一个用来处理图像的软件。我有很多图像(超过11000个),当我在几分钟后执行我的程序时,我有一个“OutOfMemoryException” 这是我的代码: private void GenerateImages() { try { Parallel.ForEach(listImagesStart, startImg => { bool docontinue = true; t

我正在用C语言开发一个用来处理图像的软件。我有很多图像(超过11000个),当我在几分钟后执行我的程序时,我有一个“OutOfMemoryException”

这是我的代码:

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
}