如何处理内存堆栈重载

时间:2012-07-09 12:53:05

标签: c# image-processing stack-overflow emgucv

我正在尝试编程边缘检测方法。我使用过emgucv Image类。由于我需要灰度值,我已将其声明为

Image<Gray,float> MyImage = new Image<Gray,float>;

我选择一个图像并将其像素值分配到MyImage中

public void selectImage()
          { 
               OpenFileDialog opp = new OpenFileDialog();
              if (opp.ShowDialog() == DialogResult.OK)
              {                 
                   MyImage = new Image<Gray,float>(opp.FileName);
                  InputArray = new Image<Gray, float>(opp.FileName);
                  Convert.ToString(MyImage);
                  pictureBox1.Image = MyImage.ToBitmap();                
              }             
          }

当我点击边缘检测按钮时,它会调用主递归函数

private void detect_edges_Click(object sender, EventArgs e)
        {          
           hueckel_operator(1, 1);
        }

此运算符以5像素间隔重复自身。换句话说,我通过将x参数递增5来在x轴上应用它,在行的末尾我将y轴增加5,依此类推。

在hueckel_operator中,再次计算非常重的公式的函数“a()”被调用8次。这是a()函数

 public double a(int j,  int counter6,  int counter7)
            {

                for (int II = 0; II <= j ; II++)
                {
                    for (KK = 1; KK < 70; KK++)
                    {
                         x_value = input_i_x(KK); //this function brings the x coordinate
                         y_value = input_i_y(KK); // this function brings the y coordinate

                result += HueckelDisk(x_value,y_value,j) * MyImage[x_value+counter6, y_value+counter7].Intensity;
                //MyImage.Dispose();
                    }
                }                           
                return result;
            }

但问题是大约在坐标(75,5)处抛出堆栈溢出异常。我用性能分析调试它,MyImage似乎吃了所有的内存。您可能希望看到递归函数,但由于它太大我不能把它放在这里,我确信递归函数(hueckel_operator())无法达到终止条件,因为我发现它被调用了多少次。我想要的是找出是否有另一种方法以更有效的方式计算“结果”。

我的另一个问题是,对象MyImage在函数a()中使用69 * j次,是否意味着每当调用()时它都会分配69 * j次的内存空间?

在我绝望的尝试期间,我已经声明并将几乎所有变量定义为全局变量以减少内存使用量,因为无论何时调用hueckel_operator()和a(),本地变量都会在堆栈中分配额外的内存这是一种好的或必要的方法吗?

我使用4个非常嵌套和繁重的函数,我不使用任何类。这会是主要问题吗?说实话,我没有看到任何东西转换成课程。

我知道,我问了太多问题,但我现在非常绝望。几个星期后我正在阅读文章,我想我需要一个开始。任何帮助将不胜感激。

enter image description here

1 个答案:

答案 0 :(得分:3)

堆栈溢出异常与内存使用并没有太大关系 - 它来自 stack 用法。在你的情况下,一个递归调用。

递归只能如此深,直到堆栈耗尽。一旦发生这种情况,您的堆栈就会溢出。

如果你在无限递归中但是你需要更深入,你可以在创建一个线程时指定堆栈大小,并在其上运行你的递归函数:

var stackSize = 10000000;
var thread = new Thread(new ThreadStart(StartDetection), stackSize);

但是,默认大小为1MB - 对于大多数任务来说这是相当多的。您可能希望验证您的递归实际上不是未绑定的,或者您无法减少或删除它。