Is it necessary to write a specific memory manager ?

This is a discussion on Is it necessary to write a specific memory manager ? within the Game Programming forums, part of the General Programming Boards category; Hi ! I'd like to know whether it looks reasonnable to you gurus to write a whole game using the ...

  1. #1
    Registered User
    Join Date
    Jun 2002
    Posts
    13

    Is it necessary to write a specific memory manager ?

    Hi !

    I'd like to know whether it looks reasonnable to you gurus to write a whole game using the standard memory manager of the operating system. Or is it necessary to write new allocation routines and a specific garbage collector ? I guess that might depend on the operating system. I'm specifically interested in win98, xp, and linux. What's your opinion ?

    Thanks in advance
    Morglum

  2. #2
    Has a Masters in B.S.
    Join Date
    Aug 2001
    Posts
    2,267
    if your asking if you should release you own memory the yes, you should.

    if you using dll's you 'll have to write an allocaction and deallocation wrapper inside the dll if you plan on allocating memory between it and the main program since the do not share heaps, something as simple as

    void* dll_alloc(int size)
    {
    return (void*) malloc(size);
    }

    void dll_free(void* mem)
    {
    free(mem);
    }

    otherwise its not strictly necessary, it really depends on what your doing.
    ADVISORY: This users posts are rated CP-MA, for Mature Audiences only.

  3. #3
    Intranasal Heroin User Xterria's Avatar
    Join Date
    Sep 2001
    Location
    Buffalo, NY
    Posts
    1,035
    LOL its GURRRRR

  4. #4
    Registered User Coder's Avatar
    Join Date
    Aug 2001
    Location
    Cairo, Egypt
    Posts
    128
    I'd like to know whether it looks reasonnable to you gurus to write a whole game using the standard memory manager of the operating system
    No one can change the standard memory manager of the operating system. The OS mem manager works completely invisible to you.

    All you can change is the C Run-Time memory manager, which is very different from the OS mem manager. Paul "Midnight" Nettle ( A guru. A real one, he's worked on "Fly!" ) has an article about that at his column on flipcode that deals with memory managers. It even includes the source code for a sample memory manager created by him ( You can get that at his website too : www.graphicspapers.com , I think )

    Custom memory managers help you to debug problems more efficiently ( if you know what you're doing ), and Paul Nettle's is a good example ( it displays debug output on mem leaks, to log files ).
    Muhammad Haggag

  5. #5
    Registered User
    Join Date
    Jun 2002
    Posts
    13
    Thanks for your replies !

    Coder, by "writing my own memory manager", I mean : begin with the allocation of a big buffer (using a malloc or a new), and then allocate&deallocate myself memory inside of this buffer. Anyway, is there any other way to do ?

    I've tried your link, I've seen the article of Nettle, but I can't see where's it's about memory managing.

  6. #6
    geek SilentStrike's Avatar
    Join Date
    Aug 2001
    Location
    NJ
    Posts
    1,141
    The only reason you would need to is if allocating memory is a slowdown in your game.
    Prove you can code in C++ or C# at TopCoder, referrer rrenaud
    Read my livejournal

  7. #7
    Registered User
    Join Date
    Feb 2002
    Posts
    114
    You don't need to allocate this heap of memory and then use memory from there, although it is a quite nice feature since you only have one pointer to release when the app exit, and it'll take care of all memory release... but if you don't know what your doing, handeling this memory will be hell, since you are typically rewriting the original memoryhandling... your memoryhandling must be faster then the original malloc/free, otherwise you loose speed...

    another way would be to overload the new and delete operator to store and remove a pointer to the object in some kind of garbage collector, when the collector shuts down, it deletes all the remaining pointers and give a warning that there where potential memory leeks...

  8. #8
    Registered User
    Join Date
    Feb 2002
    Posts
    114
    Oh... and I dont see any reason to have an memoryomanager handling the game engines memory, only use the memorymanager for the game related objects... you'll never know what those gamescript-programmers will do when you're on coffee break! you'll better controll them with an memory manager... hehe

  9. #9
    Registered User
    Join Date
    Jun 2002
    Posts
    13
    Ninebit,

    your post was very instructive for me, because I didn't know that it was possible to replace the by-default new&delete operators. Of course, it's possible to overload them, but they do (AFAIK) two things :

    1) allocate memory
    2) call the constructor

    With my memory manager, I can do point 1). But is it possible in c++ to do point 2) ?

    Could you show me an example of well written operator new, which does points 1) and 2) ?

    Thanks in advance !

  10. #10
    Registered User
    Join Date
    Jun 2002
    Posts
    13
    Oh, and by the way, here are the reasons for which I'm attempting to replace win98's standard alloc routines :

    1) win98 is very bad at reusing freed memory. When you do 1000 news and 1000 deletes interleaved together, you can't be sure that the news will use the space freed by the deletes.
    2) my routines are faster than window's, because they are much simpler. They do nearly nothing (in fact they do only store the information necessary to the garbage collector). All is in the garbage collector, who is indeed expensive to call, but the programmer is free to choose where to call it (typically when the game's idle or when changing of level).

  11. #11
    Registered User Coder's Avatar
    Join Date
    Aug 2001
    Location
    Cairo, Egypt
    Posts
    128
    by "writing my own memory manager", I mean : begin with the allocation of a big buffer (using a malloc or a new), and then allocate&deallocate myself memory inside of this buffer.
    This will never work. Windows is a multi-tasking operating system, both through the use of multi-threading & multi-processing. Taking a large portion of the memory as a single buffer by your program, will leave windows & all running apps crawling, your app included.

    Windows memory management CANNOT be replaced, because it's simply invisible. All you can do is call malloc() or new() and that's it. Windows gets you memory, sometimes it's from the physical memory, sometimes it's from the virtual memory ( your hard disk ).
    Windows memory management includes memory defragmentation ( if it does any ), and coordinating physical and virtual memory, passing memory to processes as needed.

    You cannot do this simply because :
    1 - You don't know about other processes and their needs.
    2 - You don't know about windows and its memory needs ( windows uses memory )
    3 - You can only use memory allocating functions, whether low-level like malloc() or high-level like new()

    The term "memory management" for a program means to replace the standard C-Runtime memory manager, and this includes replacing new() & delete(), not just overriding.

    The C-Runtime ( replacable/custom ) memory manager is a good example of what your memory manager would do - in a better way ofcourse, otherwise you have no reason to write a mem manager.

    1 - The C-Runtime mem manager has an internal memroy structure called _CrtMemBlockHeader, representing a memory block. It keeps a linked list of these memory blocks. Each block holds important information. For the debug memory manager, this structure holds the line & name of the file that allocated the memory, for example.

    2 - The debug memory manager allocates more memory than you request. It allocates an additional 16 bytes, by default. 8 bytes before your memory block ( head ) and 8 bytes directly after your memory block ( tail ).

    3 - It then fills these additional bytes with a pre-defined value, this fill is called a no-mans-land fill. These bytes should never be touched by your program, if it doesn't have a bug ( == if it doesn't cross memory boundaries ). When you see this value in a variable ( in the debugger ) you know you've crossed your boundaries somewhere.

    4 - After that, it fills the allocated memory with a pre-defined value. When you see this value ( as a value of a variable ) you know you're using uninitialized memory.

    5 - When releasing the allocated memory, the manager checks the head & tail padding bytes. If any byte contains a value other than the pre-defined value, then you have a bug somewhere. A bug that caused you to access in-accessible memory ( through crossing the boundaries of an allocated array, for example ). An assertion - possibly - displays a message box telling you that you messed things up, along with the information about the messed block.

    6 - After that, it fills the released bytes with another pre-defined value. Thus whenever you see this value, you know you're using released memory ( happens often ).

    7 - The memory manager also keeps track of the amount of memory allocated & released. It updates this count whenever you allocate/de-allocate something.

    This is a very bad simplification of what the memory manager does, but it gives you an idea what you can do and what you can't do.

    When you write your manager, you can manage your linked list in any way you like, you can choose any no-mans-land fill size ( Paul Nettle used 1024 for heavy-weight debugging ), you can choose your own values for such blocks.

    Paul chose the value of 0xDeadBeaf ( hexa decimal ) for newly allocated memory. Thus whenever whenever you see this value in a debugger ( as the value of any variable ) you know you're using uninitialized memory ( Smart name, right? )

    He also chose the value 0xBAADF00D for the released memory, so that you can detect bugs when released memory is being used.

    Additionally, Paul logged any memory allocations to a text file. And on exit, he'd check the lined list of blocks. If it contains a block ( i.e. a forgotten block == memory leak ) it outputs that block to a log file with a question mark next to it, so that you know you forgot to allocate it.


    I'm not sure if you read the correct article, here's the full address :
    http://www.flipcode.com/cgi-bin/msg....m=askmid&id=-1

    I failed to find the manager source ( I didn't search enough, after all ). I believe you'll find it on graphicspapers.com via ftp ( ftp.graphicspapers.com ) or http

    1) win98 is very bad at reusing freed memory. When you do 1000 news and 1000 deletes interleaved together, you can't be sure that the news will use the space freed by the deletes.
    Since now you know you can't change this, you don't have to worry about that. More people are using Win2K & XP, which are much better ( At least Win2K is LOADS better. I've not tried XP, but it should be since it uses much of the same technology )

    2) my routines are faster than window's, because they are much simpler. They do nearly nothing (in fact they do only store the information necessary to the garbage collector). All is in the garbage collector, who is indeed expensive to call, but the programmer is free to choose where to call it (typically when the game's idle or when changing of level).
    Well, they're definitely not faster. Because the windows routines run all the time, transparently.
    Windows does a million things you don't see ( Win2K for example, gives each process a separate memory space, as if it's running alone )


    My advice to you is to forget about replacing the windows routines, unless you're programming an OS ( maybe you should examine linux? ), and as far as I see, you're not.

    Additionally, forget about replacing the standard C-Runtime mem manager for a while. Believe me, it won't do you any good now. If you're a starter on game programming ( or even an intermediate programmer ) don't bother doing this.
    Writing a custom memory manager would be beautiful, it's a rich experience. But only do it when it's the suitable time.
    Muhammad Haggag

  12. #12
    Registered User
    Join Date
    Jun 2002
    Posts
    13
    Thank you very much, Coder, for your reply. I've learned many things, and the link now works.

    There's only one point that I don't understand : why should my memory manager have any problems with the other programs ? The other programs would simply continue to use the standard memory manager of windows, and the fact that my program uses a different memory manager should be transparent to them. I'm not sure that I've clearly explained what I was doing. I'm only doing a "pooled" memory management, i.e., I begin my program with, for example,

    Code:
    unsigned int *pool = new unsigned int [1048576]; // allocates 4MB
    unsigned int *free_space = pool;
    then my alloc routine does :
    Code:
    unsigned int *buf = free_space;
    free_space += required_space + HEADER_SIZE;
    FillTheHeader
    return buf;
    my free routine does :
    Code:
    MarkTheHeaderToRememberThatItHasBeenFreed
    (Of course, in my program that's much more complicated, due to the garbage collector).

    So, Coder, do you see any problem with that code ?

  13. #13
    Registered User Coder's Avatar
    Join Date
    Aug 2001
    Location
    Cairo, Egypt
    Posts
    128
    I wasn't talking about bugs in your code. It's just that when you allocate a pool of memory ( like your 4MB ) you'll be reserving this memory and preventing windows from giving it to other process. This would make windows run slower.

    Mostly, you will never be using all your 4MBs, chances are that you'll be having useless - extra - memory allocated. This is a waste, if you don't have a use for this memory you should let windows use it.

    Try increasing this 4MB to 32 MBs for example, and you'll notice the overall slowness of the system.

    That's all I meant when I warned you of doing so.
    Hope this helps.
    Muhammad Haggag

  14. #14
    Registered User
    Join Date
    Jun 2002
    Posts
    13
    Ah, then there's no problem, because the ratio mem used / mem requested will be > 90%, because in fact I don't allocate 1 big pool, but I do allocate many small ones. For example, in a video game that will use between 40 and 150 MB of RAM, I can allocate pools of 4 MB each. (Assuming that no allocated object will be of size > 4MB).

    Thanks again,
    Morglum.

  15. #15
    Sayeh
    Guest
    Actually, there is no problem with using the O/S Memory Managers to do what you need. In almost all commercial games, the developers allocate all the dynamic memory they need right up front for all their buffers, pixmaps, bitmaps, masks, sounds, etc. They don't do it continuously on the fly during game operations.

    The only problem with the O/S memory manager, and it will do this to your program regardless of whether or not you use it, is it might offload portions of your code and RAM to disk-- this is the VMM aspect of windows.

    You can probably set flagbits in the memhandles telling the memory manager that your ram is never to be unloaded (paged out), but that could create other headaches.

    I read Paul Nettle's columns and didn't see him actually say you couldn't touch the O/S memory manager. anyone who thinks you can't is sadly misinformed. The only reason Paul has had to write memory managers is because the code he's worked with has not followed that simple performance rule I stated eariler-- allocate in the beginning only, dispose at the end. A game should not be doing any allocation/deallocation during game play because that's cycle-consumptive.

    if you are really sharp, of course you can modify the O/S Memory Manager behavior-- that's called trap patching. You could patch the whole memory manager out and make everyone including the O/S use your own, if you wanted. But only a select handlful of people even remember how to do that now. And you really have to understand what the O/S is doing so that you can work with it, rather than creating a breaking point.

    There is no such thing as a "run-time" memory manager unless your running a language like Java, or some other interpreted language, or you're using something like MFC (Microsoft Foundation Class) for C++. It's all just more unnecessary layers.

    As a developer, not you specifically, if you can't manage memory, which is trivial, then you should not be developing. Find another career.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. Assignment Operator, Memory and Scope
    By SevenThunders in forum C++ Programming
    Replies: 47
    Last Post: 03-31-2008, 06:22 AM
  3. available memory from task manager
    By George2 in forum Tech Board
    Replies: 10
    Last Post: 01-18-2008, 01:32 AM
  4. using task manager to monitor memory
    By George2 in forum Tech Board
    Replies: 12
    Last Post: 01-13-2008, 07:56 AM
  5. How to write a session manager?
    By Logan in forum C++ Programming
    Replies: 0
    Last Post: 04-25-2006, 06:34 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21