Another newbie question (100% cpu usage and memory leak)
Justin Slowik

hey i'm working on getting the basic components down for a game I am working on in my spare time, and I have just started doing keyboard initiated movement. However,if I open the task manager while the program is running, it shows CPU usage at 100%, and if I move my character up and down, my pagefile usage and overall memory usage slowly climb. Here's the main parts of my movement code:

Main (skipped over basic initialization code):

  while(!(key[KEY_ESC])){    //begin main game loop
    if (keypressed())
    {    
      animatePC(character_data,landFile,playerPos);
      clear_keybuf();
    }
  }

animatePC:

1void animatePC(const DATAFILE *character_data,const DATAFILE *landFile, position &playerPos)
2{
3 
4 BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H);
5 int newY = playerPos.posY;
6 if(key[KEY_DOWN]){ //if down key is hit, walk down to next tile
7 int count = 0;
8 for(; newY < playerPos.posY + 32 ; newY++)
9 {
10 if(count == 2)
11 count = 0;
12 else
13 count++;
14 buffer = draw_map(landFile);
15 draw_sprite(buffer,(BITMAP *)character_data[count].dat,0,newY);
16 DrawDoublebuffer(buffer);
17 destroy_bitmap(buffer);
18 }
19 count = 0;
20 
21 }
22 else if(key[KEY_UP]){ //else if up key is hit, walk up to next tile
23 int frameCount = 11;
24 for(; newY > playerPos.posY - 32 ; newY--)
25 {
26 if(frameCount == 12)
27 frameCount = 10;
28 else
29 frameCount++;
30 
31 buffer = draw_map(landFile);
32 draw_sprite(buffer,(BITMAP *)character_data[frameCount].dat,0,newY);
33 DrawDoublebuffer(buffer);
34 destroy_bitmap(buffer);
35 }
36 frameCount = 11;
37 }
38 playerPos.posY = newY;
39}

Doublebuffer Code:

void DrawDoublebuffer(BITMAP *buffer) {
    acquire_screen();
    blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
    release_screen();
}

and finally Drawmap

1BITMAP *draw_map(const DATAFILE *landFile)
2{
3 BITMAP *buff = create_bitmap(SCREEN_W, SCREEN_H);
4 clear_bitmap(buff);
5 
6 int mapXtotal = 20 * 32;
7 int mapYtotal = 18 * 32;
8 for (int x = 0; x < mapXtotal; x = x+32){
9 for (int y = 0; y <= mapYtotal; y = y+32){
10 draw_sprite(buff,(BITMAP *)landFile[0].dat,x,y);
11 }
12 }
13 int size = text_length(font, versionNumber.c_str()); //display version number
14 textout_right_ex(buff, font, versionNumber.c_str(), SCREEN_W-10, SCREEN_H-10, makecol(255,255,255), -1);
15 return buff;
16}

any help for fixing either of these problems would be greatly appreciated. as far as I can tell I'm destroying all bitmaps after they're used, so I dont know why the memory usage continues to climb every time I move in a direction. As for the 100% cpu, I'm assuming its cause I'm constantly checking for a keypress. if thats the reason for it, is there an easy way to fix this? any help would be greatly appreciated. thanks

Matthew Leverton

Regarding 100% CPU usage, you'll have to throw a rest(1) in there somewhere. Keep in mind that it will probably rest for 10ms. Or you can rest(0) which "plays nice," but still uses 100% CPU.

gnolam

And as for the memory leak, you never destroy "buff" in draw_map().

That said, don't recreate your buffers every time. It's horribly inefficient. Create them once at the start of the program and destroy them once at the end.

Also, look into separating your logic and your drawing...

[EDIT]
If I were you I'd dump the acquire and release as well when I was at it, as you're only doing one operation to the screen. Chances are that, one day, you'll be tempted to put something that doesn't belong there in between them... and then your program will die a gruesome death.

Justin Slowik

thanks for the rest() idea. that fixed the cpu time a bunch! now as for the leak I seem to be having, i realized its not my main memory thats leaking anymore, it does increase while moving but when I stop it goes back down again. however, my pagefile usage does climb slowly but surely. And I'm afraid after an extended period of time I'll overflow. Any other ideas on that? the pagefile seems to climb 1-5 MB every time I move 1 tile space.

[edit]
thanks gnolam for the advice. I'll be separating stuff out at some point, right now I'm just trying to get the basics down as they come to me. I'll be separating into classes and such probably later in the weekend. And i'll look into the tips you gave me now, see if any of them affect the mem usage.

ReyBrujo

I believe your code has a great memory leak. See function animatePC. You create a buffer. But you only destroy it a couple of times inside for cycles. Your function should be like this instead:

1void animatePC(const DATAFILE *character_data,const DATAFILE *landFile, position &playerPos)
2{
3 
4 BITMAP *buffer = create_bitmap(SCREEN_W, SCREEN_H);
5 int newY = playerPos.posY;
6 if(key[KEY_DOWN]){ //if down key is hit, walk down to next tile
7 int count = 0;
8 for(; newY < playerPos.posY + 32 ; newY++)
9 {
10 if(count == 2)
11 count = 0;
12 else
13 count++;
14 buffer = draw_map(landFile);
15 draw_sprite(buffer,(BITMAP *)character_data[count].dat,0,newY);
16 DrawDoublebuffer(buffer);
17 }
18 count = 0;
19 
20 }
21 else if(key[KEY_UP]){ //else if up key is hit, walk up to next tile
22 int frameCount = 11;
23 for(; newY > playerPos.posY - 32 ; newY--)
24 {
25 if(frameCount == 12)
26 frameCount = 10;
27 else
28 frameCount++;
29 
30 buffer = draw_map(landFile);
31 draw_sprite(buffer,(BITMAP *)character_data[frameCount].dat,0,newY);
32 DrawDoublebuffer(buffer);
33 }
34 frameCount = 11;
35 }
36 playerPos.posY = newY;
37 destroy_bitmap(buffer);
38}

Justin Slowik

ReyBrujo, I tried your idea, and it just made my pagefile leakage climb at least 2 or 3 times faster. shrug This is gonna drive me insane hah. lets see if i clean up my code how i do.

ReyBrujo

Hehehe, the problem is that draw_map is creating bitmaps that are never being destroyed too. This code should work. Don't create a bitmap inside animatePC:

1void animatePC(const DATAFILE *character_data,const DATAFILE *landFile, position &playerPos)
2{
3 
4 BITMAP *buffer;
5 int newY = playerPos.posY;
6 if(key[KEY_DOWN]){ //if down key is hit, walk down to next tile
7 int count = 0;
8 for(; newY < playerPos.posY + 32 ; newY++)
9 {
10 if(count == 2)
11 count = 0;
12 else
13 count++;
14 buffer = draw_map(landFile);
15 draw_sprite(buffer,(BITMAP *)character_data[count].dat,0,newY);
16 DrawDoublebuffer(buffer);
17 destroy_bitmap(buffer);
18 }
19 count = 0;
20 
21 }
22 else if(key[KEY_UP]){ //else if up key is hit, walk up to next tile
23 int frameCount = 11;
24 for(; newY > playerPos.posY - 32 ; newY--)
25 {
26 if(frameCount == 12)
27 frameCount = 10;
28 else
29 frameCount++;
30 
31 buffer = draw_map(landFile);
32 draw_sprite(buffer,(BITMAP *)character_data[frameCount].dat,0,newY);
33 DrawDoublebuffer(buffer);
34 destroy_bitmap(buffer);
35 }
36 frameCount = 11;
37 }
38 playerPos.posY = newY;
39}

Justin Slowik

Thanks Rey! that fixed it now. I appreciate the help now i cna move on w/ my life hah.

A J

create_bitmap() is a signifacnt cost, only do it if you have to.
also ALWAYS check its return code, so if it actaully worked.

Thread #585495. Printed from Allegro.cc