lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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
system. 

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
don?t 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
next.

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 don?t
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.

- DC

> -----Original Message-----
> From: lua-bounces@bazar2.conectiva.com.br 
> [mailto:lua-bounces@bazar2.conectiva.com.br] On Behalf Of Jose Marin
> Sent: Thursday, 11 May 2006 10:53 PM
> To: lua@bazar2.conectiva.com.br
> Subject: Managing dynamic objects
> 
> 
> Hi.
> 
> 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 
>