Originally Posted by
WILL
Well our game is not using object pooling, and we have to put it in, but I'm wondering if that may be a bigger problem than we think. The game does create and destroy objects, but not consistently. How much of a performance hit can your game take while you are not creating or destroying objects without the object pooling implemented?
Based on documentation I read about Object pooling it laregly depends on what kind of a bocjets are you using.
If you are using objects which are only stored in memory (have no external resources) the Object Pooling may actually be slower. Why? On returning the object into object pool you need to reset it state to initial one manually.
So if your object contains lots of variables you need to change every one of them to some starting value. Now you can skip reseting every varable state to some initial but this could in some cases lead to unexpected behavior.
Originally Posted by
WILL
Are there other memory management issues such as Garbage Collection kicking in at other times for other reasons?
Also based on Object pooling documentation using it can make Garbage Colection procedures take longer time.
Also, most garbage collectors scan "live" object references, and not the memory that these objects use for their content. This means that any number of "dead" objects without references can be discarded with little cost. In contrast, keeping a large number of "live" but unused objects increases the duration of garbage collection.
[1] In some cases, programs that use garbage collection instead of directly managing memory may run faster.
Also the main problem in Object pooling is that you need seperate pools for each object type. ANd to make most out of it you need to predict the optimal number of pooled objects and this I belive is far from being easy in a computer game.
Now if you are concerend with memory usage of your game I suggest that you first try to implement data sharing approach (mutiple objects share same common data).
For instance you have your ingame unit whose class loks like this:
Code:
TMonster = class(TObject)
private
FHealth: Integer;
FMaxHealth: Integer;
FName: ShortString;
FDescription: String;
FPosition: TPosition;
FOrientation: TOrientation;
FAttack: Integer;
FSpeed: Integer;
end;
You can quickly see that some of the data from that class is being duplicated for every created object. So to reduce the memory requirement you actually split that class into two seperate ones.
One that holds the often changing data:
Code:
TMonsterDynamic = class(TObject)
private
FHealth: Integer;
FPosition: T3DPosition;
FOrientation: TOrientation;
FMonsterData: TMonsterStatic;
protected
function GetMaxHealth: Integer;
function GetName: ShortString;
function GetDescription: String;
function GetAttach: Integer;
function GetSpeed: Integer;
public
property MaxHealth: Integer read GetMaxHealth;
end;
Code:
function TMonsterDynamic.GetMaxHealth: Integer;
begin
if FMonsterData <> nil then
result := FMonsterData.FMaxHealth
else result := 0;
end;
And the one that holds often static data:
Code:
TMonsterStatic = class(TObject)
FMaxHealth: Integer;
FName: ShortString;
FDescription: String;
FAttack: Integer;
FSpeed: Integer;
end;
This can reduce the memory consumption a lot especially when you have large number of objects.
I'm writing a detailed tutorial on using this approach but unfortunately I'm not sure when it will be finished. I hope soon.
Bookmarks