Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

memory leak on game loop

I am creating a game in javascript and my gameloop is called every 30ms, it leaks a lot of memory as task manager shows the firefox memory usage to increase by 400mb in about 20 seconds. I am not familiar with how to make sure memory is collected in javascript.

function GameLoop(tick) {
  move(player1.ship);
}

function Player(name) {
  this.id = 0;
  this.name = name;
  this.ship = Ship(this);
}

function Ship(player) {
  this.pos = [1024/2, 768/2];
  this.vel = [0, 0];
  this.angle = 0;
  this.acc = 0;
  this.thrust = 0;
  this.west = 0;
  this.east = 0;
  this.turnRate = 5;
  this.player = player;
  this.size = [40, 40];
  this.ship = canvas.rect(this.pos[0], this.pos[1], this.size[0], this.size[1]);
  this.ship.attr("fill", "red");

  return this;
}

function move(ship) {
  var angle = ship.angle;
  var max_speed = 20;
  var acc_speed = 300;

  var acc = 0;
  if (ship.thrust) {
    acc = 0.25 * acc_speed;
  }
  else { //slow down
    if ((acc - (0.25 * acc_speed)) > 0) {
      acc -= 0.25 * acc_speed;
    }

    else {
      acc = 0;
    }
  }

  var speedx = ship.vel[0] + acc * Math.sin(angle);
  var speedy = ship.vel[1] - acc * Math.cos(angle);
  var speed = Math.sqrt(Math.pow(speedx,2) + Math.pow(speedy,2));

  var speedx = ship.vel[0] + acc;
  var speedy = ship.vel[1] - acc;
  var speed = speedx + speedy;

  if (speed > max_speed) {
    speedx = speedx / speed * max_speed;
    speedy = speedy / speed * max_speed;
  }
  ship.vel = [speedx, speedy];
  ship.pos = [ship.pos[0] + speedx * 0.25, ship.pos[1] + speedy * 0.25];
  ship.ship.attr({x: ship.pos[0], y: ship.pos[1]});
  ship.ship.rotate(angle);
  ship.angle = 0;

  delete this.thrust;
  delete this.west;
  delete this.east;
  delete old_angle;
  delete angle;
  delete max_speed;
  delete acc_speed;
  delete acc;
  delete speedx;
  delete speedy;
  delete speed;

  return this;
}

var player1 = new Player("Player 1");
setInterval(GameLoop, 30);

Ok I commented out some code and have found the offending line, its

ship.ship.rotate(angle); After commenting that line out javascript is using 4500K. any idea why this is causing the problem, and how can I still rotate my object without this bit of code?

like image 212
code_by_night Avatar asked Jan 04 '12 23:01

code_by_night


People also ask

Does Infinite Loop cause memory leak?

Stack memory leaks occur when a method keeps getting called but never exits. This can happen if there is an infinite loop or if the method is being called with different data each time but the data is never used. Eventually, the stack will fill up and the program will run out of memory.

How do you fix memory leaks in games?

The most obvious is simultaneously running multiple memory-hogging applications—4K video editing software, or a ridiculously large number of tabs open in a browser—that use up all available memory resources. The solution to this issue is to install more RAM, and/or have the computer run fewer programs simultaneously.

What is the main cause of memory leaks?

Memory leak occurs when programmers create a memory in heap and forget to delete it. The consequences of memory leak is that it reduces the performance of the computer by reducing the amount of available memory.

How do you tell if a game has a memory leak?

Running out of memory is the simplest way to identify a memory leak, and it's also the most common approach to uncovering one. That's also the most inconvenient way to find a leak. You'll probably notice your system slowing down before you run out of RAM and crash your application.


2 Answers

The documentation of rotate in RaphaelJS says the following:

Adds rotation by given angle around given point to the list of transformations of the element.

That certainly sounds like a potential culprit. The critical words there are add and list.

What does the transform function show you when you rotate an element twice? My suspicion is that calls to rotate accumulate larger and larger transformation strings. if that's what's happening, you can reset the transform,

el.transform("");

and that should clear the problem you're seeing.

like image 99
dyoo Avatar answered Oct 13 '22 05:10

dyoo


I don't see anything in your code snippet which would leak memory.

As pointed out by Eugen Rieck, Firefox (and others) sometimes don't do GC and/or free memory they have allocated until they actually have a reason to do it.

Have you tried using an actual memory profiling tool to see if your code is actually leaky? I'm not sure if Firefox has one, but there's one at least in Chrome.

like image 45
Jani Hartikainen Avatar answered Oct 13 '22 05:10

Jani Hartikainen