Pooling Objects – LibGdx Memory Management

Sharing is caring!

What is Pooling?

Pooling is a technique that allows the program to repurpose objects that are no longer being used in order to manage memory and decrease processing time. Imagine a box with 10 objects inside, this would be your pool and when you want an object you simply open the box and take out an object. You keep doing this until you have enough objects. Once you’re finished with the object you simply put it back in the pool so it can be taken out again when it’s needed instead of making a new object every time you need one. This is the pool decreasing processing time by having all the objects ready in a pool to use. In the case of memory management a pool creates a lot of objects at the start of the game and places them in memory so they are all grouped together in memory which means the space in memory will be less susceptible to memory fragmentation issues. This technique is commonly used for things like bullets and enemies in a game.

Why use pooling?

If you create a game where the main character can shoot a mini-gun and you have 60 bullets being shot per second then every frame you will be creating a new object which has a performance hit to your game and this performance hit will continue all through your game every time the main player fires his weapon. Now if you have a pool which creates 600 bullets and your player fires you will no longer creating objects every frame and instead be using one of the 600 bullets already created. Since you have 600 items in your pool you should have 10 seconds worth of objects already created and since bullets travel fast then they should have hit an objects or flew off screen within 10 seconds and those “dead” bullets can be put back in the pool ready to be used again. This eliminates the time needed to create the objects all through the game and instead creates the objects once at the start of the game.

What happens if I use all the objects in the pool?

If you happen to use all the objects in the pool then new ones will be created. The cost of creating these objects is still present however it will only happen once whereas non pooling methods would have these objects created every time.

Creating a pool

To create a pool for any object requires a couple of classes. One class which will be your poolable object(in our case a bullet) and second, a pool which will hold our objects. Our first step is to create a bullet class that implements the poolable interface.

In the bullet class we implement the poolable interface and override the reset method which will be called each time the bullet is freed and resets our bullet data. We also have an update method which we will use to update our bullets position and finally a couple of methods for setting the bullets initial position and direction.

Our second step is to create the pool which is in charge of creating new objects, freeing and resetting our objects once our program is finished with them.

Here we extend the Pool and override the protected newObject method which should create and return a new Bullet. We also add a couple of constructors so we can create this pool with an initial amount other than the default of 16 and a max amount other than the default unlimited.

Using the pool

We have so far created both required classes for object pooling and now we only need to implement this into our application. To do that we first have to create the pool and an array to hold our live bullets.

Next we need a method of adding new bullets. In this example we will use a mouse click to signal that a bullet should be added to the screen.

In our touchDown method we first use our bulletPool to get a new bullet from our pool with the obtain call. We then fire the bullet by telling the bullet its new position and direction. Next we add this bullet to our activeBullets array so we can access it later in our render method. Finally, a System.out call to output the amount of free objects left in the pool. This will output 0 for each bullet fired until the first bullet is replaced into the pool then this will report how many objects are in the pool ready to be used.

Our final step is to render the bullets and do their logic.

In this example I have used the shapeRenderer to render our bullets but in a game you would probably use a spriteBatch with some textures. In our first loop we update and render the bullets then in our second loop we check if they have left the application window. If the bullet has left the window we use the bulletPool to free the bullet as it is no longer on screen and should be placed back in our pool for use again. We then remove it from our array of active bullets so it is no longer rendered. If the bullet is not removed from our active bullet array the bullet would be rendered at 0,0.

Pooling Bullets
Bullets being fired

Pooling will increase the amount of memory and processing required when used to pool small amounts and should only be used when lots of object will be created. Another thing to note is that if an object from the pool is referenced to other objects it will still be referenced to those object even when the object is freed so you will need to unlink the object manually when it is freed.

 

The official LibGDX guide on pooling can be found here and the wikipedia entry for pooling can be found here.

 

Sharing is caring!

2 Replies to “Pooling Objects – LibGdx Memory Management”

  1. thanks!

  2. Thanks a lot!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.