There's a lot of literature on this topic,
http://www.cs.kent.ac.uk/people/staff/rej/gc.html has 1900 entries...
but probably the classic from the perspective of your comment, is the
AED Storage package (circa 1967)
http://portal.acm.org/citation.cfm?doid=363534.363546
Basically, there is nothing to prevent you from keeping your own list
of storage and recycling it yourself
if you have a situation in which the generality of garbage collection
is not needed. This was supported
extensively in Lisp machine systems, and there are examples of how you
can go about allocating pools of storage in Common Lisp in several
texts. Sometimes called "resources" I think. This is good for I/O,
but also other tasks where memory speed is a keyl
In my own recent programming using big integers from GMP, I "compiled"
code from ordinary lisp into a register-style simulated machine, where
I allocated a few registers of pre-allocated GMP numbers, and
then furiously re-used them because I knew when they were no longer
needed. Of course in those circumstances, reference counting was
entirely unnecessary as well. Oh, and if I ran out of registers, I
just allocated another one.
When I was done, and if the system needed more storage, then the GC
would collect the structures around
the GMP numbers, and the deallocation of the GMP stuff would be called
by the GC in a finalization step.
There are other probably more important memory issues for really large
problems, but it is not clear what you should optimize for. Do you
expect to do some arithmetic on 2-megabyte numbers? If so, cache
considerations are far more importance than if you are mostly doing
stuff that fits in some cache.
Copying GCs can help maintain cache coherence. Conservative GCs do
not. Reference counts -- I suppose this relies on good luck in
patterns of allocation and deallocation, which may be likely.
RJF