2012-06-14 47 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

我想通了。事實證明,這不完全是我的錯。編寫顏色選擇器代碼的人使用的顏色格式不同於我,但我們有時使用的引擎會隱式地將一種格式轉換爲另一種格式,這就是爲什麼它有時仍然有效。非常非常奇怪。 感謝您的幫助,雖然傢伙!