Recent

Author Topic: BGRABitmap huge memory leak  (Read 4947 times)

Khelle

  • Newbie
  • Posts: 6
BGRABitmap huge memory leak
« on: December 23, 2011, 12:12:50 am »
Hi guys!
Currently Im working on some Arkanoid-like project.
I was forced to use Pascal, so I chose Lazarus, but telling the truth I have never written anything graphical in Pascal-like language before.
Now, arkanoid is half-ready , but I have problem with EOutOfMemory in BGRABitmap.
Im using TTimer to draw game current state every 40 ms using function:

Quote
procedure TForm1.DrawGame;
var
  i, j, k: Integer;
  t1,t2,t3,t4,t5: TBGRABitmap;
begin
  // rysujemy tlo
  bimg := TBGRABitmap.Create(ClientWidth, ClientHeight, BGRAPixelTransparent);

  bimg.FillRect(disc_x, disc_y, disc_x+disc_width, disc_y+disc_height, BGRA(255,192,0), dmSet);
  bimg.FillRect(0, 0, clientWidth, 40, BGRA(100,100,100), dmSet);

  t1 := TBGRABitmap.Create('./graphics/tile_1.png'); t2 := TBGRABitmap.Create('./graphics/tile_2.png'); t3 := TBGRABitmap.Create('./graphics/tile_3.png'); t4 := TBGRABitmap.Create('./graphics/tile_4.png'); t5 := TBGRABitmap.Create('./graphics/tile_5.png');
  for i := 0 to 19 do begin
     for j := 0 to 18 do begin
        if (tiles[i+1][j+1] > 0) then begin
           k := tiles[i+1][j+1];
           if (k = 1) then begin img := t1; end else if (k = 2) then begin img := t2; end else if (k = 3) then begin img := t3; end else if (k = 4) then begin img := t4; end else begin img := t5; end;
           bimg.PutImage(game.tmargin+game.tile_w*j, game.tile_h*i+100,img,dmDrawWithTransparency);
        end;
     end;
  end;
  t1.Free; t2.Free; t3.Free; t4.Free; t5.Free;

  img := TBGRABitmap.Create('./graphics/ball.png');

  bimg.PutImage(ball.x,ball.y,img,dmDrawWithTransparency);

  img := TBGRABitmap.Create('./graphics/life.png');
  for i := 1 to game.lives do begin
     bimg.PutImage(clientWidth-(img.Width+5)*i-5,5,img,dmDrawWithTransparency);
  end;

  bimg.FontHeight := 30;
  //bimg.FontAntialias := true;
  //bimg.FontStyle := [fsBold];
  bimg.TextOut(5,5,'Poziom: ' + IntToStr(game.level) + ', wynik: ' + IntToStr(game.pts),BGRA(255,255,255));


  bimg.Draw(Canvas, 0, 0, True);
  bimg.Free;
end; 

But the problem is that, at the beginning of game it uses about 6 MB RAM, after 1-2 minutes it goes to about 50-60 MB, a ten crushes causing EOutOfMemoryError.

Would anyone of you be willing to answer me what Im doing wrong and how to fix it?       

SONFEDAI

  • Jr. Member
  • **
  • Posts: 55
Re: BGRABitmap huge memory leak
« Reply #1 on: December 23, 2011, 12:19:09 am »
  img := TBGRABitmap.Create('./graphics/life.png');
Where is the img.free?
I'm using
   Lazarus: 0.9.3.1
   Date: 2011-11-05
   FPC: 2.5.1
   SVN Ver.: 29060

Khelle

  • Newbie
  • Posts: 6
Re: BGRABitmap huge memory leak
« Reply #2 on: December 23, 2011, 12:33:55 am »
Ah, yes, I was rewriting this fragment so many times I forgot about that - I mean I thought it was somewhere there - now I feel embarrassed  :-[

Thank you, SONFEDAI, It was helpful, however I DIDNT solve my problem.
Memory leak was not so big, but there still was. Now program caused EOutOfMemory error after 4-5 minutes getting 50-60 MB RAM.

What is still wrong there?

EDIT:
Ah, and I forgot to add, I also use at the beginning:
Code: [Select]
procedure TForm1.FormPaint(Sender: TObject);
begin
  DrawGame();
end;
« Last Edit: December 23, 2011, 12:59:40 am by Khelle »

circular

  • Hero Member
  • *****
  • Posts: 4220
    • Personal webpage
Re: BGRABitmap huge memory leak
« Reply #3 on: December 23, 2011, 02:36:31 am »
There is no free either for "img := TBGRABitmap.Create('./graphics/ball.png');"

Anyway, you should not load all these images for each frame. To make it faster, you need to put these instructions in FormCreate event, and free theses images in FormDestroy.
Conscience is the debugger of the mind

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: BGRABitmap huge memory leak
« Reply #4 on: December 23, 2011, 03:04:06 am »
Turn on heaptrace (-gh) with line number debug info (-gl), I suggest to also uncheck windows GUI application (-WG) because without it the memory leak trace would be printed via message box, which could be annoying. Run your program for a while (until you think it has reached the leak point) and terminate. Your program will dump a backtrace where the leak occurs, that's the point where you allocate the memory. You can then decide when to free it.

 

TinyPortal © 2005-2018