As you've noted any straight 'reference count strategy' can lead to thrash in this instance.
one simple solution would be to potentially load a resource as a 'sticky' resource, which always
exists even if no reference is present.
another, way which is more elegant, is to setup your objects as recyclable.
for instance, though your bullets are only seen somtimes, you keep them in a 'recycler', when you need one
a 'free' one is given to you, if no free ones exist one is added and given. when the object is 'done' you release it back to the free list. this means you will also avoid general new/delete thrash, and since the objects which reference the images
never die until the program ends, the images wont either.
Apologies if this post is too long or tending towards being OT. It
started as a short answer and grew.
I have used two solutions to this problem in the past. The first is
reusable pools of objects, as suggested by Raymond. Each factory/manager
has its own pool of objects that get reused over the life of the game.
At suitable times the entire pool can be reset back to a pristine state
(changing levels is a good time for this). Other advantages are that the
allocated memory needs of the game are known in advance and the memory
pool sizes can be adjusted to just accommodate the peak needs of that
The second is lower level. Rather than rely on the default system memory
allocation, I have used custom allocators. The allocator is given a
block of memory to start with which is subdivided as needed. But rather
than return deallocated blocks to the general store, it maintained free
lists of convenient sizes (powers of 2). So if a request for 120 bytes
came in, the free list of 128 byte blocks could be checked first. In
this way, the free lists of different size objects act in a similar way
to the reusable object pools, but at a lower level. The disadvantage is
that more initialisation work needs to be done on the memory (since you
dont know what was there previously) but the advantage is that these
free lists are shared across the whole system.
Generally allocations have a 8 byte overhead (blocksize and free list
next pointer). I store this value at the start of the block then
increment the pointer before returning the memory. With a little more
work you can add another 4 bytes to the end of the block and write a
sentinel value into it. This can then be checked for buffer overruns
when the memory is deallocated. You could even maintain a list of
allocated blocks and iterate this list once an update and check the
sentinel value to catch buffer overruns even sooner.
Again at convenient times this memory allocator can be compacted, with
all free lists returning to the general heap and all adjacent blocks
being merged. I do this after unloading one level but before loading the
To prevent permanent fragmentation, objects that have a very long
lifecycle (systems that last the entire game for example) could be
allocated from the general system heap at the same time that the
allocator memory is itself allocated. That way the large holes that
could otherwise impede compaction are avoided.
In my current project I am using this custom allocator method rather
than object pools, primarily because I am using lua. This means I dont
need to change lua's dynamic memory use, but I can be confident that
memory is not fragmenting too much.
I have used these two ideas successfully in games on platforms ranging
from mobile phones and GBA to PS2 and PC.
> -----Original Message-----
> From: [hidden email] > [mailto:[hidden email]] On Behalf Of Jose Marin
> Sent: Thursday, 11 May 2006 10:53 PM
> To: [hidden email] > Subject: Managing dynamic objects
> My game will have many dynamic objects (actors,
> bullets, explosions, etc).
> Most of them will be created during the game, have a
> short life and is deleted.
> What's the best strategy when you have many objects
> that will be created/destroyed during the game?
> I would like to avoid memory trashing.
> Yahoo! doce lar. Faça do Yahoo! sua homepage.
> http://br.yahoo.com/homepageset.html >