Sign in to follow this  
sarriss696

Memory

Recommended Posts

Hi, im re-writting my game engine because i came accross a couple of good snags in why it shouldnt be used one of them was memory management, I dont really know much about it but ive searched the internet a fair bit etc and still not sure what im looking for i was told good memory management needs to handle garbage and fragmentation stuff etc, I was wondering if anyone has found a decent article or something from a book that could help me :) if not atleast point me in the right direction thnx for any help and apologies for a probably well answered question that i n00bishly cant seem to find

Share this post


Link to post
Share on other sites
From my understanding unless you're going to make some good money off the engine, memory management isn't worth the hassle. Firstly it involves overloading the new operator so you actually know how much memory is being used and were its being created. Forcing objects to be created in chunks that wont separate them across ram and so forth. I'd look into the benefits against the time it takes to implement it, then ask your self why you want it.

Share this post


Link to post
Share on other sites

first question is, how much memory are you allocating? and how often are you allocating memory?

basically, all good engines use some form of pool allocator. at startup, the engine will grab a bunch of large blocks of contiguous memory (ie: pools) and will allocate out of those pools, instead of using the bare heap.

why do this? well, it comes down to how you access memory. and if your writing a teeny game with a handful of objects, its really probably not worth doing, but if you want to have big scenes, with lots of objects, particles, etc, using a pool system becomes very useful. for the following reasons.

- you can allocate different pools to different kinds of memory (eg: graphics resources in GPU friendly ram).
- for objects which are both small, and allocated frequently (like particles) using a pool will massively reduce heap fragmentation (as only the pool will get fragmented). and you can happily 0 the entire pool when your not displaying particles, eliminating fragmentation entirely.
- it puts a hard limit on the size of your resources, and the memory footprint your game will use. if you run out of memory, you will know exactly where, and why.
- using a pool for level objects, means that when you leave the level, you can simply 0 the entire pool. no more leaks (as long as nothing is holding resources which point to the pool of course!).
- you can defragment a pool at runtime. of course doing this means that anyone holding a reference or pointer to your data must be holding a weak pointer to it. this is generally a good idea anyway, boost has one you can use.
- you can garbage collect from pools at runtime. usually using a reference counted system. can be useful, but also needs things like dead pool lists to keep objects around for a few frames until downstream references are released, etc.

on large games (ala commercial titles), each subsystem will get its own pool, and maximum budget. and its up to each subsystem to dole out memory from that pool as it sees fit. the UI subsystem might get 20mb of ram, out of which needs to come fonts, UI, textures, etc. the resource system might grab 256mb of ram, 128mb of which is a pool for models, 64mb for textures, and 64mb for level objects.. etc etc.

For your own stuff, having a few different pools can be useful, having a separate pools for things like particles is a godsend (and even if you only use pooling for particles, it still helps a lot), and a separate pool for your level objects. can make life a lot easier.

It really comes down to how often, and how much memory your allocating. allocating a lot of very small objects, and then deleting them shortly afterwards will not make the heap a happy place.

personally, ive had it drilled into me over various console tiles to avoid the heap like the plague . There are lots of great pool allocator algorithms out there (eg: slab) but its only worth it if your allocation patterns are problematic.

Share this post


Link to post
Share on other sites
A simple memory manager used in a lot of commercial games is the mark/release system: 1, 2.

From my perspective, the rules of YAGNI/KISS mean that Garbage collection (other than simple reference-counting) and Defragmentation is a waste of time.

Share this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
A simple memory manager used in a lot of commercial games is the mark/release system: 1, 2.

From my perspective, the rules of YAGNI/KISS mean that Garbage collection (other than simple reference-counting) and Defragmentation is a waste of time.


I agree, its worth getting some pools in, get some simple ref counting going. and if you really need it, you can bolt on defragging later. (as long as you adhere to the pointers to things in pools being weak pointers).


Share this post


Link to post
Share on other sites
Quote:
Original post by sarriss696
i was told good memory management needs to handle garbage and fragmentation stuff etc


This is only true if you really want to go that route, i.e. try to come up with a 100% managed memory system. In that case, I suggest you code directly in Java, C# or Python or some other language that offers a fully managed environment. Note that even those don't do automatic defragmentation as far as I know (although there's no reason why they couldn't), since in modern PCs the address space is just large enough to avoid the issue.

Very often in games (and especially on consoles), memory management is not just handled as a black box, but the actual game code is designed to work with the best practices of using memory resources. This means that the memory management layer offers the game layer support code like shared_ptrs, memory pools, arenas, heaps and other abstractions that the game programmer finds convenient. In the context of consoles with small amount of memory, it is preferred to have the game programmer manually organize the data loading so that fragmentation is avoided, instead of indirecting your memory accesses through relocatable memory handles that would do defragging automatically for you.

In summary, memory management in unmanaged setting is not a black box, and good memory management lets the game programmer *avoid* memory leaks and fragmentation from occurring (instead of trying to solve it after it has occurred).

Don't know about any of this and don't even want to care about any of this? Use Java, C# or Python, they will (mostly) make memory issues go away, and you can focus on your game instead.

Share this post


Link to post
Share on other sites
Thank you all for the very quick replies,

tbh my game so far will probably be fairly small,

so yes memory management might not really be neccessary but i plan on building on this game slightly later one with things like multi-texturing etc, and i got told things like that eat away at your memory,so while im building my engine from scratch again I thought now would be a good time to put in memory management and ive had to learn it from scratch,

pain in the backside lol and i must admit the other languages sound tempting but im afraid i have to stick with C++, for particular reasons that probably would full up the forum database lol,

Thnx for the help with options and definatly thnx for the good explanations you all provided, they were a very helpful insight into what i need to look into and what i Should be looking into, pools sounds like fun hehe :D

thnx all :)

Share this post


Link to post
Share on other sites
Quote:
Original post by clb

Note that even those don't do automatic defragmentation as far as I know (although there's no reason why they couldn't)


Generational garbage collection performs "defragmentation" on each garbage pass. As surviving old data gets copied into new heap, it also compacts the memory.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Quote:
Original post by clb

Note that even those don't do automatic defragmentation as far as I know (although there's no reason why they couldn't)


Generational garbage collection performs "defragmentation" on each garbage pass. As surviving old data gets copied into new heap, it also compacts the memory.


Oh, thanks for the correction!

Share this post


Link to post
Share on other sites
I don't think that anyone has mentioned that a correctly implemented pool is lightning fast to allocate from. If you implement your pools as freelists of same-sized objects, then allocation and freeing from the pool is only a few cycles. A heap allocation can be hundreds of cycles. Another advantage of freelists is that they don't suffer from fragmentation at all. So there is no need for any fancy runtime defragmentation system.

Freelists can use slightly more memory if you dont know how many objects of that type/size you need (because you need to have enough free in the freelist). If you know exactly how many of a certain object you will have in a level (trees/plants/rocks for instance) then you can create a freelist with that number of free objects when you load the level.

You could even allocate another chunk from the heap when the freelist runs out and stick that chunk at the end of the freelist to make it more dynamic.

Share this post


Link to post
Share on other sites
Simple example. Imagine 42 squintillion-bytes of memory (the exact definition of a squintillion isn't important). Now lets say that every second byte is allocated. Now, even though you have 21 squintillion bytes left, you cannot allocate more than one byte at a time, because there are no two adjacent bytes that are free for use.

This is fragmentation, there are so many fragments of memory allocated such that you can no longer allocate chunks of memory despite there being memory available.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this