2012-06-14 46 views
1

我有一个内存泄漏的地方。我已经搜索了很多次,而且对我来说看起来很稳固。我只是..不能...找到它... 好吧,背景。这是一个堆栈驱动的洪泛填充,这一点代码是我添加一些东西到堆栈的唯一位置。有更多的代码,所以如果没有人可以找到内存泄漏,我会再发布一些内容。洪水填充算法内存泄漏

这是关于这个的最奇怪的部分。代码只用一种颜色+线条艺术(pictexture)就可以正常工作,但是当使用多种颜色并使用填充桶时,我会发现那些奇怪的内存泄漏。

//descend to the floor 
      while(true) 
      { 

       if(++iterator > total) 
       { 
        Debug.Log("broke in the stupid down loop..."); 
        break; 
       } 

       //if we hit line art or a color we're not changing, break out of the loop 
       if(PicTexture.GetPixel((int)coords.x, (int)coords.y).a > .5f || 
        MyTexture.GetPixel((int)coords.x, (int)coords.y) != ColorToChange || coords.y < 0) 
       { 
        break; 
       } 


       //if we're looking right and find an open spot in our texture 
       if(reach.right && MyTexture.GetPixel((int)coords.x + 1, (int)coords.y) == ColorToChange 
        && PicTexture.GetPixel((int)coords.x + 1, (int)coords.y).a < .5f) 
       { 
        reach.right = false; //search it and stop looking right 
        if(!search.Contains(new Vector2((int)coords.x + 1, (int)coords.y))) 
         search.Push(new Vector2((int)coords.x + 1, (int)coords.y)); 
       } 
       else 
       { 
        if(MyTexture.GetPixel((int)coords.x + 1, (int)coords.y) != ColorToChange 
         || PicTexture.GetPixel((int)coords.x + 1, (int)coords.y).a >= .5f) //if theres a wall and we're not looking right 
         reach.right = true; //look for an opening to the rightq 
       } 

       //same thing for left 
       if(reach.left && MyTexture.GetPixel((int)coords.x - 1, (int)coords.y) == ColorToChange 
        && PicTexture.GetPixel((int)coords.x - 1, (int)coords.y).a < .5f) 
       { 
        reach.left = false; 
        if(!search.Contains(new Vector2((int)coords.x - 1, (int)coords.y))) 
         search.Push(new Vector2((int)coords.x - 1, (int)coords.y)); 
       } 
       else 
       { 
        if(MyTexture.GetPixel((int)coords.x - 1, (int)coords.y) != ColorToChange 
         || PicTexture.GetPixel((int)coords.x - 1, (int)coords.y).a >= .5f) 
         reach.left = true; 
       } 

       MyTexture.SetPixel((int)coords.x, (int)coords.y, BrushColor); 
       coords.y--; 
      } 

编辑:我只是意识到我忘了提到最奇怪的部分。此代码工作得很好,直到我使用起始颜色以外的颜色(蓝色)。一旦我改变颜色,即使它变回蓝色,它仍然会破裂。

+6

你怎么知道你有内存泄漏?你遇到什么症状?你曾经使用过哪些调试工具来确定泄漏的来源?他们展示了什么? –

+0

我一直在使用Unity的Debug.Log()来引发调试语句,以查看搜索堆栈的大小,以及该迭代器如果卡住了,可以将其从循环中取出。当我只使用一种颜色时,堆栈大小永远不会超过75,并且迭代器保持合理的计数。我一直在600,000次迭代中打破循环,堆栈大小为100,以防止程序崩溃。 –

+0

我不认为这是一个内存泄漏,但与您的算法问题 – Carsten

回答

2

首先,使用一个分析器。我曾与RedGate's ANTS Memory Profiler有愉快的经历。当问题不明显时,它确实是获取所需信息的最快方法。

至于你的代码,乍一看我注意到的是,你可能会在很短的时间内创建大量的对象。我不知道这是否真的引起了你所看到的问题。

另外,GDI +作为一只狗很慢。如果您开始注意到性能不佳,您可能需要考虑使用Bitmap.LockBits来获取指向存储器中图像数据的指针并对其进行操作。根据我的经验,GDI +根本不适合处理尺寸适中的图像。

+0

我的狗很快,但是我主要使用GDI +作为矢量图形,而不是用于位图。 +1为RedGate。 –

+0

谢谢你,虽然我使用的是Unity的texture2d,但他们没有内置的本地Bitmap.LockBits函数。 这是奇怪的事情。这个代码在我启动时工作得很好。直到我改变颜色并尝试使用洪水填充,它开始行为不端。颜色应该不重要,因为它只是在寻找替代颜色。 –

0

我想通了。事实证明,这不完全是我的错。编写颜色选择器代码的人使用的颜色格式不同于我,但我们有时使用的引擎会隐式地将一种格式转换为另一种格式,这就是为什么它有时仍然有效。非常非常奇怪。 感谢您的帮助,虽然家伙!