c#中用于高速应用程序的内存管理

本文关键字:内存 管理 应用程序 高速 用于 | 更新日期: 2023-09-27 18:10:12

我正在构建一个应用程序,该应用程序处理来自文件或缓冲区的传入图像,并以固定大小的数组或双精度对象的形式输出结果。应用程序需要相对快速。我遇到了一个循环时间的问题。我在处理一张图像时开始记录循环时间,它从最小的65ms开始逐渐增加到500ms,这实在是太慢了。果然,我检查了内存使用情况,它也在稳步增长。

我在每个周期后运行GC,并尽可能多地转储未使用的变量。我不在处理循环中创建新对象。图像处理在它自己的线程上完成,因此所有的资源都被转储。似乎大部分周期时间增加发生在我从文件中提取图像时。我还能错过什么呢?

这里是粗略的代码,完整的东西相当大。主要功能>

 public void Vision()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        try
        {
            AlignmentParams.ApproximateNumberToFind = 1;
            AlignmentParams.SearchRegionMode = 0;

            AlignmentResult = AlignmentPat.Execute(cogDisplay1.Image as CogImage8Grey, null , AlignmentParams);
            Fixture.InputImage = cogDisplay1.Image;
            Fixture.RunParams.UnfixturedFromFixturedTransform = AlignmentResult[0].GetPose();
            Fixture.Run();
            AlignmentResult = null;

        #region FindLineTools 
        #endregion 
        #region FindEllipse 
        #endregion 

                sw.Stop();
                SetText("V" + sw.ElapsedMilliseconds.ToString() + Environment.NewLine);


        }
        catch (Exception err) 
        {
           SetText(Environment.NewLine + "***********Error***********" + Environment.NewLine);
           SetText(err.ToString() + Environment.NewLine);
           SetText("***************************" + Environment.NewLine);
        }


    }

c#中用于高速应用程序的内存管理

首先,我建议发布一个干净的代码,以获得更好的可读性(删除所有注释掉的东西)。其次,只关注最重要的部分,即:您的问题是由于繁重的图像处理导致的内存过度使用/泄漏(如果错误,请纠正)。因此,在名为Vision的线程中,在处理完成后立即取消对图像对象的引用并将其设置为null(如上所述,GC在您的情况下没有多大帮助)。下面的代码片段简要地演示了这个概念:

    public void Vision()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            try
            {
                AlignmentParams.ApproximateNumberToFind = 1;
                AlignmentParams.SearchRegionMode = 0;
                    AlignmentResult = AlignmentPat.Execute(cogDisplay1.Image as CogImage8Grey, null , AlignmentParams);
                Fixture.InputImage = cogDisplay1.Image;
                Fixture.RunParams.UnfixturedFromFixturedTransform = AlignmentResult[0].GetPose();
                Fixture.Run();
                AlignmentResult = null;
            // your coding stuff
                    sw.Stop();
                    SetText("V" + sw.ElapsedMilliseconds.ToString() + Environment.NewLine);
            }
            catch (Exception err) 
            {
               SetText(Environment.NewLine + "***********Error***********" + Environment.NewLine);
               SetText(err.ToString() + Environment.NewLine);
               SetText("***************************" + Environment.NewLine);
            }
finally{Fixture.InputImage=null}

不要调用GC.Collect。让虚拟机决定什么时候内存不足,什么时候必须进行收集。您通常不能很好地决定GC的最佳时间。收集,除非您正在运行其他心跳或空闲的监视线程。

其次,确保您从方法调用中接收到的任何资源都被dispose了。将变量设置为NULL不会这样做,你应该显式地调用Dispose或Using块:

using(SomeResource resource = Class.GiveMeResource("image.png"))
{
   int width = resource.Width;
   int height = resource.Height;
   Console.Write("that image has {0} pixels", width*height);
} //implicitly calls IDisposable.Dispose() here.

您还需要做一些内存和调用分析来检测哪里(如果有的话)存在泄漏