2015-03-03 4 views
2

Я пишу плиточную игру на C#. Но я столкнулся с проблемой, когда приложение находится в оконном режиме, моя системная память колеблется около + -300 МБ, а в полноэкранном режиме она использует всю память и выбрасывает исключение OutOfMemoryException.C# Утечка памяти с растровым изображением

Я не могу найти места, где я забуду. Задайте объекты .Dispose(), которые могут вызвать это, насколько я знаю.

Ближайшее я могу определить, что проблема заключается в том месте, где я .Clone() растровое изображение в PictureBox.Image. Это происходит один раз в каждом кадре. У меня есть весь «мир» в памяти, который представляет собой растровое изображение размером около 2000x1000 пикселей, из которого я копирую часть, которая будет отображаться на экране.

Я мог бы прикрепить код, но так как это очень много, я подожду, пока не станет ясно, что проблема там, а не в описанном выше методе.

Благодаря

EDIT: Это где я думаю, что проблема лежит:

public Bitmap GetMap(Rectangle renderedArea) 
    { 
     if (renderedArea.Bottom > renderedMap.Height || renderedArea.Right > renderedMap.Width) 
      return renderedMap.Clone(new Rectangle(0,0,renderedMap.Width,renderedMap.Height),renderedMap.PixelFormat); 
     return renderedMap.Clone(renderedArea, renderedMap.PixelFormat); 
    } 

public void Render(Rectangle area) 
    {  
     renderArea.Image = worldEditor.map.GetMap(area); 
     Graphics g = Graphics.FromImage(renderArea.Image); 

     PointF stringPoint = MouseInputEventHandler.CursorLocation.ToCoords(worldEditor.map.TileArray.TileSize,worldEditor.RENDER_START); 
     g.DrawString(string.Format("{0},{1}", (int)stringPoint.X, (int)stringPoint.Y), new Font("Arial",15,FontStyle.Bold), Brushes.Yellow, new PointF(6, 6)); 
     g.Dispose(); 
    } 

Глядя на смежные вопросы (! Которые Google не показал мне), я обнаружил, что добавление этого к Рендер() решает проблему:

if (renderArea.Image != null) 
      renderArea.Image.Dispose(); 

Однако я хотел бы услышать, почему это тоже нужно утилизировать.

+0

Без кода, это будет трудно, чтобы помочь ... – rducom

+0

Почему это downvoted? Довольно ясно, что он спрашивает. –

+0

@MillieSmith Возможно, что нижний предел был до того, как код был добавлен – BradleyDotNET

ответ

3

Когда вы Clone, вы создаете копию . Таким образом, ваш новыйBitmap объект, в конце концов, должен также иметь Dispose.

renderArea.Image = worldEditor.map.GetMap(area); 

Переназначает изображение без утилизации, поэтому вы пропускаете старый объект. Если вы добавите код из своего сообщения, вы очистите объект, исправив проблему.

Потенциально ясный способ написания было бы:

Bitmap oldImage = renderArea.Image; 
renderArea.Image = worldEditor.map.GetMap(area); 

if (oldImage != null) 
    oldImage.Dispose(); 
+0

Спасибо. У меня создалось впечатление, что старый образ будет перезаписан, если придумать новый образ, что, очевидно, было неправильным. – Michael

+0

@ user2790895 Да, ссылки не работают так: – BradleyDotNET

+0

Да, я знаю о ссылках, но я имею в виду, что старое изображение больше не будет ссылаться, когда новый займет его место, и поэтому не должно быть GarbageCollected? – Michael

Смежные вопросы