2012-06-14 6 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으로 즐거운 경험을했습니다. 문제가 분명하지 않을 때 필요한 정보를 얻는 가장 빠른 방법입니다.

코드에 대해 처음 보았을 때 매우 짧은 시간에 많은 수의 Vector2 개체를 생성 할 수 있습니다. 이것이 실제로 당신이보고있는 문제를 일으키는 지 나는 모른다.

제쳐두고 GDI +는 개로 느립니다. 성능이 좋지 않다는 것을 알기 시작하면 Bitmap.LockBits을 사용하여 메모리의 이미지 데이터에 대한 포인터를 얻고이를 조작하는 것이 좋습니다. 내 경험에 의하면 GDI + 단순히 겸손한 크기의 이미지 조작에 적합하지 않습니다.

+0

개가 아주 빠르지 만 비트 맵이 아닌 벡터 그래픽을 위해 주로 GDI +를 사용했습니다. RedGate +1. –

+0

유니티의 texture2d를 사용하고 있지만 Bitmap.LockBits 네이티브 함수가 내장되어 있지 않습니다. 이상한 일이 있습니다. 이 코드는 시작할 때 잘 작동합니다. 내가 색을 바꿀 때까지 그리고 홍수 채우기를 사용하여 오작동을 일으키기 전까지는 아닙니다. 교체 색상 만 찾고 있기 때문에 색상은 중요하지 않습니다. –

0

나는 그것을 알아 냈다. 그것은 완전히 내 잘못이 아니라는 것이 밝혀졌습니다. 색상 선택기 코드를 작성한 사람은 나보다 다른 색상 형식을 사용하고 있었지만 때때로 사용하는 엔진은 한 형식을 다른 형식으로 암시 적으로 변환하므로 가끔씩은 여전히 ​​효과가있었습니다. 매우 이상합니다. 도움을 주셔서 감사합니다.