Memory Management

Started by
1 comment, last by Omaha 22 years, 5 months ago
I was going to start today on the memory management aspect of my project, and I just want to make sure I have the right idea before I start hacking away at it. Hmm... bad choice of words there. I grab a big chunk of memory and keep it handy. Then, whenever I''ll need memory for program related material, I grab a handful of that "hunk" and keep track of where it''s located. When I don''t need it anymore, I just tell the hunk it''s good for use again. I''m aware there is alot more stuff it can do, but do I have the basic jist right?
Advertisement
Yep, thats a good way to start.

Some other things you can do when you start to make it more advanced:

- For debug builds, when you allocate a new block of memory,

a) fill that memory with a value such as 0xCD, this helps to track things like NULL pointer assignments.

b) also allocate 256 (or more) bytes more than the allocation requested. 128 of those should go before the pointer you return to the client and 128 of those should go after the block you return. These two 128 areas should be filled with a distinctive value such as 0xFD. Doing this helps you track places where the client code overwrites past the block it allocated. (When the allocation is free''d you check that both 128byte areas are still set to the value they should be (0xFD)).

c) when memory is free''d fill all of the block with a distinctive value such as 0xCC. This can help to track places where client code uses memory after it was free''d.

These 3 are things done by the C runtime library allocator.


- If you''re feeling adventurous you could go for a handle based allocation system. Instead of returning the memory address of a block directly from allocation requests you return a handle which refers to a block. If the client wants to write to or read from a memory block, they call a Lock() function passing the handle of that memory block.
This has some very nice advantages - mainly that the allocation system is free to move blocks of memory around without the client being broken. This can be good for avoiding fragmentation - when an allocation is free''d, blocks either side of it can be moved to close up any gaps. Therefore you get 0% fragmentation regardless of what order things are allocated or free''d.


- If you''re interested in tracking where allocations are made etc, you could add a "name" parameter to your allocation call so that every allocated block has a name. This could just be the sub-system which made the allocation or a complete description ("graphics", "AI", or "main menu sprites") or you could even list the source file and line number. If you decide your app is taking too much memory you can trivially ask the memory manager to tell you who allocated what.


- Finally you can have different "lifetimes" for allocations. The allocate function could take a parameter which tells the allocator how long something will be around for. Values could be "whole of the application", "front end", "in game", "for this level", "for this frame", "scratch". This lets you have different allocation pools (less fragmentation) and also allows you to have a single function to free all allocations with a particular lifetime or less. So at the end of the current level of a game you''d do freeMultipleAllocations( for_this_level ); - saves time and can reduce fragmentation if used with pools.


There''s plenty of other things you can do - just depends on your needs, how much debugging support you need etc.

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Thanks for the suggestions. I had an idea sort of like your handle idea, but I was going to keep track of all the allocated blocks by keeping a copy of their pointers handy. If I needed to move things around in the "hunk" I could then change the values so they still correctly pointed to the new information (after I moved the data around, of course.)

Also, perusing the Quake source (which gave me some ideas on this thing) I noticed there was a listing of what resources reside in what portions of their "hunk." Is there any reason I should try and so something similar, like allowing the allocation function to specify whether the block should be allocated at the end or the beginning or something? That would complicate things a bit and I don''t know if it''s a worthwhile investment. I was thinking about it and it seems to me I wouldn''t need to do that since I''m using OpenGL for the graphics and therefore textures wouldn''t be stored there, and that seemed to be one of the major portions of id''s memory hunk. Remnants of the original version, I suppose.

This topic is closed to new replies.

Advertisement