[SDL/C++] Garbage Collection

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?

Greets
Christoph

Hello.

A fairly clean method of handling any resource (memory isn’t the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying to juggle pointers. Using boost’s smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

If looking at all those templates makes your eyes bleed, liberal use
of “typedef” can really help.

When all else fails hand writing your own RAII wrapper classes.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

Hope this gives you some ideas,
Brian.On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?

Check out this:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/

Take time to read the limitations

Julien

— En date de?: Mar 27.1.09, Brian <brian.ripoff at gmail.com> a ?crit?:de: Brian <brian.ripoff at gmail.com>
Objet: Re: [SDL] [SDL/C++] Garbage Collection
?: “A list for developers using the SDL library. (includes SDL-announce)”
Date: Mardi 27 Janvier 2009, 14h04

Hello.

A fairly clean method of handling any resource (memory isn’t the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying to juggle pointers. Using boost’s smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

If looking at all those templates makes your eyes bleed, liberal use
of “typedef” can really help.

When all else fails hand writing your own RAII wrapper classes.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

Hope this gives you some ideas,
Brian.

On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Thanks for the quick answers.
What do you use?
Clean up memory manually or do you use some type of garbage collection?
(This question goes to the complete mailing list ^^)

Greets
Christoph

julien CLEMENT schrieb:> Check out this:

http://www.hpl.hp.com/personal/Hans_Boehm/gc/

Take time to read the limitations

Julien

— En date de : Mar 27.1.09, Brian /<brian.ripoff at gmail.com>/ a ?crit :

De: Brian <brian.ripoff at gmail.com>
Objet: Re: [SDL] [SDL/C++] Garbage Collection
?: "A list for developers using the SDL library. (includes
SDL-announce)" <sdl at lists.libsdl.org>
Date: Mardi 27 Janvier 2009, 14h04

Hello.

A fairly clean method of handling any resource (memory isn't the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying
 to juggle pointers. Using boost's smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

If looking at all those templates makes your eyes bleed, liberal use
of "typedef" can really help.

When all else fails hand writing your own RAII wrapper classes.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

Hope this gives you some ideas,
      Brian.

On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich <@Christoph_Friedrich> wrote:
> Hi,
>
> does anybody know a good garbage collection library I can use in my game
> which is portable like SDL?
>
> How do you manage dynamic memory?
_______________________________________________
SDL mailing
 list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I would advise you to use the new shared_pointer from boost

http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm

Or if you are on windows, the latest Visual C++ 2008 SP1 express already
supports tr1 out of the box.–
Paulo

On Tue, Jan 27, 2009 at 2:08 PM, julien CLEMENT wrote:

Check out this:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/

Take time to read the limitations

Julien

— En date de : Mar 27.1.09, Brian <brian.ripoff at gmail.com> a ?crit :

De: Brian <brian.ripoff at gmail.com>
Objet: Re: [SDL] [SDL/C++] Garbage Collection
?: “A list for developers using the SDL library. (includes SDL-announce)” <
sdl at lists.libsdl.org>
Date: Mardi 27 Janvier 2009, 14h04

Hello.

A fairly clean method of handling any resource (memory isn’t the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying
to juggle pointers. Using boost’s smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

If looking at all those templates makes your eyes bleed, liberal use
of “typedef” can really help.

When all else fails hand writing your own RAII wrapper classes.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

Hope this gives you some ideas,
Brian.

On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?


SDL mailing
list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Most of the time, my projects are small enough to make manual memory
management easy or I use some form of the RAII method mentioned. I have
made a class specifically for juggling SDL_Surfaces, though. To me, it
depends on the project. For a game, I would not use garbage collection, but
try to be smart about memory allocation and deletion (so that it rarely
happens in-game).

Jonny DOn Tue, Jan 27, 2009 at 8:53 AM, Christoph Friedrich < seija at dragons-server.de> wrote:

Thanks for the quick answers.
What do you use?
Clean up memory manually or do you use some type of garbage collection?
(This question goes to the complete mailing list ^^)

Greets
Christoph

julien CLEMENT schrieb:

Check out this:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/

Take time to read the limitations

Julien

— En date de : *Mar 27.1.09, Brian <brian.ripoff at gmail.com><brian.ripoff at gmail.com>

  • a ?crit :

De: Brian <brian.ripoff at gmail.com> <brian.ripoff at gmail.com>
Objet: Re: [SDL] [SDL/C++] Garbage Collection
?: “A list for developers using the SDL library. (includes SDL-announce)”

Date: Mardi 27 Janvier 2009, 14h04

Hello.

A fairly clean method of handling any resource (memory isn’t the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying
to juggle pointers. Using boost’s smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

If looking at all those templates makes your eyes bleed, liberal use
of “typedef” can really help.

When all else fails hand writing your own RAII wrapper classes.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

Hope this gives you some ideas,
Brian.

On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?


SDL mailing
listSDL at lists.libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org



SDL mailing listSDL at lists.libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

For those looking to shift handling of SDL surfaces to a RAII object,
Boost’s intrusive_ptr works pretty well for this. Something like:

typedef boost::intrusive_ptr<SDL_Surface> SurfacePtr;

Then you need to provide the following connections into SDL’s surface
reference counting setup:

void intrusive_ptr_add_ref(SDL_Surface* surface)
{
++surface->refcount; // Not sure “refcount” is the exact name.
}

void intrusive_ptr_release(SDL_Surface* surface)
{
SDL_FreeSurface(surface);
}

Just make sure that when you initially pass your raw pointer to
SurfacePtr’s constructor that you pass the correct value to the
"addref" parameter (it defaults to true). Otherwise it may add a
reference, which because newly created surfaces already have refcount
== 1, you may not want.

Peter

2009/1/27 Jonathan Dearborn :> Most of the time, my projects are small enough to make manual memory

management easy or I use some form of the RAII method mentioned. I have
made a class specifically for juggling SDL_Surfaces, though. To me, it
depends on the project. For a game, I would not use garbage collection, but
try to be smart about memory allocation and deletion (so that it rarely
happens in-game).

Jonny D

On Tue, Jan 27, 2009 at 8:53 AM, Christoph Friedrich wrote:

Thanks for the quick answers.
What do you use?
Clean up memory manually or do you use some type of garbage collection?
(This question goes to the complete mailing list ^^)

Greets
Christoph

julien CLEMENT schrieb:

Check out this:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/

Take time to read the limitations

Julien

— En date de : Mar 27.1.09, Brian <brian.ripoff at gmail.com> a ?crit :

De: Brian <brian.ripoff at gmail.com>
Objet: Re: [SDL] [SDL/C++] Garbage Collection
?: "A list for developers using the SDL library. (includes SDL-announce)"

Date: Mardi 27 Janvier 2009, 14h04

Hello.

A fairly clean method of handling any resource (memory isn’t the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying
to juggle pointers. Using boost’s smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

If looking at all those templates makes your eyes bleed, liberal use
of “typedef” can really help.

When all else fails hand writing your own RAII wrapper classes.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

Hope this gives you some ideas,
Brian.

On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?


SDL mailing
list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org



SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

(I wrote this from my phone, and it accidentally replied to the sender instead of the list the first time. Sorry about that…)>On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?

If you want automatic garbage collection that actually works and is
accurate, you need to use a managed language, with al the performance
tradeoffs that come with it. The Boehm GC was written for Java
originally, and only works as well as it does because it can tell
what’s an object reference and what isn’t.

Unmanaged languages like C++ don’t have that advantage. Pointers are just integers; they
only have a special significance to the compiler and the coder. So you
get a lot of false positives because any integer (or combination of 4
chars in a string) that looks like a pointer to a variable is treated
as a valid reference. (It gets worse if you’re compiling to a 64-bit
platform, because te address space is so much larger.) And if you
start doing pointer math you can really screw the GC up!

Reference counting (smart pointers) works a lot better for unmanaged code, if
(and only if) you’re scrupulous about avoiding circular references.
But frankly, the only real way to be sure you get everything is to
clean up your own messes. For every constructor call, there should be
a matching destructor call. Make sure you free every dynamic array you
allocate. Every object should be freed by the same general region of
code that constructed it, unless it’s explicitly handed off to another
object that takes ownership of it.

Doing it yourself is a lot faster (to execute if not necessarily to write) and leads to better
programming habits. Get some tool to monitor, report and track memory
leaks if you don’t already have one. (I’m not too familiar with C++'s
capabilities. I’m used to Delphi, where the built-in default memory
manager will do that for you if you ask, but it depends on the RTTI
features of Delphi’s object model for some of its tricks, so you
couldn’t do it that way on C++.) If you can find one, it’ll help you
to learn how to manage your memory by finding the areas you still need
to improve.

Hi,

We use in our project OpenLieroX a mixture of a caching system and
smartpointers.

If some part in the code loads a map, a soundfile, a graphics-file or
a gamemod-file, it all goes directly in the cache and the next time
this data is needed it can be loaded from there.

If the cache ist too full, it flushes out some parts. There is no need
to check wether it is used somewhere else right now or not because of
the smart pointers.

SmartPointer:

The interface of the cache looks like this:

Greetings,
AlbertAm 27.01.2009 um 14:53 schrieb Christoph Friedrich:

Thanks for the quick answers.
What do you use?
Clean up memory manually or do you use some type of garbage
collection? (This question goes to the complete mailing list ^^)

Greets
Christoph

julien CLEMENT schrieb:

Check out this:
http://www.hpl.hp.com/personal/Hans_Boehm/gc/

Take time to read the limitations

Julien

— En date de : Mar 27.1.09, Brian <brian.ripoff at gmail.com> a
?crit :
De: Brian <brian.ripoff at gmail.com>
Objet: Re: [SDL] [SDL/C++] Garbage Collection
?: “A list for developers using the SDL library. (includes SDL-
announce)”
Date: Mardi 27 Janvier 2009, 14h04

Hello.

A fairly clean method of handling any resource (memory isn’t the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/
Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying
to juggle pointers. Using boost’s smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

If looking at all those templates makes your eyes bleed, liberal use
of “typedef” can really help.

When all else fails hand writing your own RAII wrapper classes.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

Hope this gives you some ideas,
Brian.

On Tue, Jan 27, 2009 at 12:59 PM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in
my game
which is portable like SDL?

How do you manage dynamic memory?


SDL mailing
list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hmm… maybe this is getting too low level for my understanding, but… when I 'read’
something, “what” is reading it? I mean, its going somewhere, right? When you say
you have to read, THEN write, you mean the reading goes, say, to the processor,
and then to the right place? Are you sure it doesnt happen at the same time?

For example, as far as I understand it, when you read a memory position, it gets
stored in the cpu and then goes to the other position? OR memory can copy from
one place to another in the same chip? (that would save a lot of traffic in the bus!)…

If
you were just copying directly, then you could do that with a DMA
transfer. Problem is, blitting is more than just direct copying. Most
sprite blits require a mask, and are performed with ANDs and ORs. (And
if you’re trying to do anything fancy, such as alpha blitting or other
blends, you’re gonna need a lot more math.) So it does need to go
through the GPU or CPU.>----- Original Message ----

From: Antonio Marcos
Subject: Re: [SDL] DirectAccess to Video Memory [was: Hello, new member reporting]

A fairly clean method of handling any resource (memory isn’t the only
resource Java!) is RAII
(http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization).
Using the standard C++ classes (std::string, std::vector<> and other
containers) instead of trying to juggle pointers. Using boost’s smart
pointer library elsewhere
(http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/smart_ptr.htm).

Spot on. I personally try to avoid raw pointers as much as possible,
at least when it comes to storage (be it on the stack or in
heap-allocated structures). Sure, it’s easy to put “delete foo” in
your destructor, or before the end of your function, but doing nothing
is even easier, and you’re also protected against an exception being
thrown, or someone later adding a “return” in the middle of a
function.

If looking at all those templates makes your eyes bleed, liberal use
of “typedef” can really help.

That and “using” declarations, but make sure to use those only in
implementation files, not header files! I also prefer to import one
class at a time rather than go “using namespace boost”, for example.

Just be aware of the limitations, in particular circular references
when using reference counted smart pointers.

That’s a pet peeve of mine, people blaming smart pointers for their
circular references, but they don’t think at all when using a smart
pointer (despite the impression their name might give!), they just go
and use “shared_ptr” all over… This is like using “delete” on every
pointer you see, because, hey, you have to free the memory, right?

shared_ptr goes hand-in-hand with weak_ptr, which goes where you would
use a pointer, but not call delete on it. What’s nice about smart
pointers is that they act as a kind of “label”, telling you what is
supposed to happen with this pointer, and the compiler helps you make
that happen: shared_ptr means that this object should live at least at
long as this pointer, weak_ptr means that it doesn’t control that
object’s lifetime, etc…

scoped_ptr is also very good (not in TR1, only in Boost, I’m afraid),
where it implements (and enforces) the simple behaviour of “delete
it when it goes out of scope, no copies allowed”. If you’re going to
pepper your code with a smart pointer, that’s the one you should use
"by default". I use them in classes most extensively.

And there’s intrusive_ptr, as Peter Mackay pointed out, which has
almost no performance overhead compared to doing by hand in C, the
overhead being possible superfluous manipulations of the refcount,
which can be avoided most of the time if you use something like “const
intrusive_ptr<SDL_Surface>&” for parameters (avoiding construction of
temporaries), and has a sizeof() equal to sizeof(SDL_Surface*) (with
optimizations, the assembly output is generally the same as what you’d
get by coding it by hand, it’s pretty amazing). But it doesn’t have a
weak_ptr equivalent, you have to use references or raw pointers for
that.

If you would like weak_ptrs anyway, you can use the custom deallocator
of shared_ptr, just passing SDL_FreeSurface as the second parameter to
the constructor (if you don’t pass that, the default is to use
"delete", which is of course wrong for an SDL_Surface!), like this:

std::tr1::shared_ptr<SDL_Surface> foo(SDL_CreateRGBSurface(0, 320,
240, 8, 0, 0, 0, 0), SDL_FreeSurface);

The downside with this is that the shared_ptr manages it’s reference
count separately, it treats SDL_Surface as something that can only be
freed once. This produces the correct behaviour, but one might cringe
at the waste of the second refcount (it is allocated on the heap).

Fewer code, fewer bugs… ;-)On Tue, Jan 27, 2009 at 8:04 AM, Brian <brian.ripoff at gmail.com> wrote:


http://pphaneuf.livejournal.com/

If you want automatic garbage collection that actually works and is
accurate, you need to use a managed language, with al the performance
tradeoffs that come with it. The Boehm GC was written for Java
originally, and only works as well as it does because it can tell
what’s an object reference and what isn’t.

It was written for C and C++, actually, and one of the magic things
about it is that it does not know how to tell what is an object
reference and what isn’t! It just keeps track of the address of every
allocated object (be it using “malloc” or “new”, both of which it
replaces with its own version), and then looks at all the (used)
memory to see if it finds references to those addresses. If an int
happens to have the same value (bitwise) as the address of an
allocated object, then it’s counted as a reference to that object.
That’s what’s called a “conservative” garbage collector: it doesn’t
try to be perfect, and if it’s not sure, it errs on the safe side and
keeps the object.

Java VMs have all the information they need, so their GCs are not
conservative. They might have different approaches (mark and sweep,
generational, etc), but they can tell what each byte of used memory
is, so they don’t have to take wild guesses (they also don’t let you
do pointer math!).

Reference counting (smart pointers) works a lot better for unmanaged code, if
(and only if) you’re scrupulous about avoiding circular references.
But frankly, the only real way to be sure you get everything is to
clean up your own messes. For every constructor call, there should be
a matching destructor call. Make sure you free every dynamic array you
allocate. Every object should be freed by the same general region of
code that constructed it, unless it’s explicitly handed off to another
object that takes ownership of it.

It can be somewhat tricky, for example in a scene graph, you might
have an object that is repeated, so using reference counting makes
sense (you don’t want to create multiple copies of the same read-only
mesh or textures). Another way is what OpenLieoX did (which I think is
pretty clever), using reference counting backed with a cache. I did
something like that once, using shared_ptr and giving it a “deleter
function” that didn’t actually deleted anything, but just marked it as
"unused" in the cache (it was for database connection pooling).

Doing it yourself is a lot faster (to execute if not necessarily to write) and leads to better
programming habits. Get some tool to monitor, report and track memory
leaks if you don’t already have one. (I’m not too familiar with C++'s
capabilities. I’m used to Delphi, where the built-in default memory
manager will do that for you if you ask, but it depends on the RTTI
features of Delphi’s object model for some of its tricks, so you
couldn’t do it that way on C++.) If you can find one, it’ll help you
to learn how to manage your memory by finding the areas you still need
to improve.

Oh! I can’t believe I skipped over Valgrind! If your platform is
supported by Valgrind (http://valgrind.org/), just use it. No if, no
but, use it. :-)On Tue, Jan 27, 2009 at 11:41 AM, Mason Wheeler wrote:


http://pphaneuf.livejournal.com/

If you want automatic garbage collection that actually works and is
accurate, you need to use a managed language, with al the performance
tradeoffs that come with it. The Boehm GC was written for Java
originally, and only works as well as it does because it can tell
what’s an object reference and what isn’t.

It was written for C and C++, actually,
Oops. I just looked that up and yeah, you’re right. I was thinking of the Java
GC (which I thought was called the Boehm GC. And now I can’t find article I
read describing where it comes from and how it works.) My mistake.

That’s what’s called a “conservative” garbage collector: it doesn’t
try to be perfect, and if it’s not sure, it errs on the safe side and
keeps the object.
That term always makes me chuckle. How would a liberal garbage collector
behave?>----- Original Message ----
From: Pierre Phaneuf
Subject: Re: [SDL] [SDL/C++] Garbage Collection

Oops. I just looked that up and yeah, you’re right. I was thinking of the Java
GC (which I thought was called the Boehm GC. And now I can’t find article I
read describing where it comes from and how it works.) My mistake.

I’m not sure the original Java VM garbage collector has a specific
name other than, uh, the “Java VM garbage collector”. :slight_smile:

It was a mark-and-sweep, stop-the-world (how do you like the sound of
that?!) GC, and I think it’s been replaced/tweaked many times since
Java 1.0, so it’s actually not too sucky nowadays. :wink:

That term always makes me chuckle. How would a liberal garbage collector
behave?

Haha! They’re called “precise” GCs, but I like “liberal”. :slight_smile:

Lots more info here:

http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)On Tue, Jan 27, 2009 at 12:35 PM, Mason Wheeler wrote:


http://pphaneuf.livejournal.com/

That term always makes me chuckle. How would a liberal garbage collector
behave?

Haha! They’re called “precise” GCs, but I like “liberal”. :slight_smile:
I know about precise GC. Doesn’t sound very liberal to me. :stuck_out_tongue:

That would make for some great coding humor. Someone ought to write up a spec for a liberal garbage collector.>----- Original Message ----

From: Pierre Phaneuf
Subject: Re: [SDL] [SDL/C++] Garbage Collection
On Tue, Jan 27, 2009 at 12:35 PM, Mason Wheeler <@Mason_Wheeler> wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?

Boost library smart pointers. Or, if you don’t need the guarantees
that reference counting gives you then use the Boehm garbage
collector. Your worst choice is to do storage management by your self.
That is the number one place where people make mistakes. Not to
mention that keeping track of all possible deallocations yourself can
cause huge code structure problems.

Bob PendletonOn Tue, Jan 27, 2009 at 6:59 AM, Christoph Friedrich wrote:

Greets
Christoph


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

±-------------------------------------+

Your worst choice is to do storage management by your self.
That is the number one place where people make mistakes. Not to
mention that keeping track of all possible deallocations yourself can
cause huge code structure problems.

I’d have to disagree with both of those assertions. The #1 source of mistakes I see, both in my own coding and in the enormous (3M+ lines of code) multitier database app I’m on the team for at work, is null pointer dereferences. (Calling things before they’ve been initialized.) #2 is off-by-one errors, and it’s a pretty distant second. Manual resource deallocation problems is probably somewhere in the top 10, but it’s certainly not #1. (Of course, YMMV in a language that doesn’t support try…finally. That makes things so much easier…)

As for “keeping track of all possible deallocations yourself,” why in the world would you want to do that? That’s not a cause of code structure problems, it’s a symptom of it. If your code isn’t already written in such a way that every object has one and only one authoritative owner at any point in the execution path, you deserve all the memory management headaches you get.

There are basically only four things that can own an object:

  1. A function. The object is created locally. Make sure you free it when you leave. C++ makes this particularly easy by letting you allocate the object on the stack, and then the compiler calls the destructor once it drops out of scope. (Just make sure that you don’t stack-allocate any object you’re going to hand to another object! Create those on the heap.)
  2. A unit (namespace.) This is also known as a global object. Globals are problematic anyway, and if you’re using them you deserve all the headaches that come with them. The one exception is singleton objects which need to be accessible to pretty much the entire program. Thing is, singletons generally don’t need to be freed anyway, since they remain in use until the program quits, at which time the OS reclaims the memory.
  3. Another object, as a sub-object. My Person class has two Arm objects, each of which has a Hand object, each of which has five Finger objects. Make sure that the destructor handles it. If your parent object has mutator functions that allow you to reassign a sub-object, make sure that the mutator handles the existing one. (It should either free it directly or does something with reference counting to make sure it’s safe to free it.)
  4. A collection. The collection should explicitly either own its objects or not own them. If it owns them, it frees them automatically as part of its own destructor. Make sure that gets called. If it doesn’t, then the object is owned by one of the other 3 owners.

I’ve been coding for years in Delphi with manual memory management only, (for objects at least; it uses compiler magic to handle dynamic arrays and strings,) following these guidelines, and only once had any problems with lost memory. Turns out I thought I was handing something to a collection that owned the objects, but it didn’t. Drove me up the wall for a few days, then someone suggested using the memory manager’s built-in functionality to track it down. Took me about an hour and a half to fix it. And I’ve never had to deal with the memory and code bloat of smart pointers or the performance issues of a manual garbage collector. It’s not really hard at all to keep track of your memory once you internalize the principles of every object having only one owner, and every owner being one of those 4 categories I mentioned.

Really, if you’re writing unmanaged code, learn to clean up your own memory. Any other way produces slow, bloated code and can also end up hiding more subtle, insidious errors.>----- Original Message ----

From: Bob Pendleton
Subject: Re: [SDL] [SDL/C++] Garbage Collection

If you have access to Visual C++, it also provides a debug heap that shows
at the end of a run
which objects were left at the heap and where they were allocated.

http://msdn.microsoft.com/en-us/library/974tc9t1.aspx

Having said that and going a bit off topic, if you can use a managed
language for your application,
I would advise it. The small hit in performance you might have, pays off in
developer productivity
and tool support.

Even though I’m quite fluent in C++, nowadays I tend to spend most of my
time on higher level languages,
and Unity3D and XNA are a good example where the games industry is heading.

Now if you application must run at full speed, or you have other
constraints, personal language taste or hardware/OS
related, then use at least some form of smart pointers, if possible.

Regards,
PauloOn Tue, Jan 27, 2009 at 8:24 PM, Bob Pendleton wrote:

On Tue, Jan 27, 2009 at 6:59 AM, Christoph Friedrich wrote:

Hi,

does anybody know a good garbage collection library I can use in my game
which is portable like SDL?

How do you manage dynamic memory?

Boost library smart pointers. Or, if you don’t need the guarantees
that reference counting gives you then use the Boehm garbage
collector. Your worst choice is to do storage management by your self.
That is the number one place where people make mistakes. Not to
mention that keeping track of all possible deallocations yourself can
cause huge code structure problems.

Bob Pendleton

Greets
Christoph


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

±-------------------------------------+


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hi,

my experience from my C++ days is that you cannot count on just yourself.

I also used to work on applications that were as big as what you are
describing, but the problem is
that not all developers were at the same level in what concerns C++
knowledge. Plus most
of the teams used to be distributed across the globe.

Belive me, it is no fun to be responsible to track down memory related
problems in the modules
you are responsible for, only to find that the real cause is a pointer
misuse made in a completly
diferent module, whose responsability is from a team in another side of the
globe.

C++ is a very powerfull language, and I still play around with it, mostly
not to forget what I once
knew, but nowadays I have better use to do with my time at work as to track
down memory problems.

Again my previous comment still holds, there are many scenarios where C++ is
a very good tool and
the best at the job, but Bob is right, with what modern C++ offers, one
should do low level memory
management only on very special cases.–
Paulo

On Tue, Jan 27, 2009 at 9:19 PM, Mason Wheeler wrote:

----- Original Message ----

From: Bob Pendleton
Subject: Re: [SDL] [SDL/C++] Garbage Collection

Your worst choice is to do storage management by your self.
That is the number one place where people make mistakes. Not to
mention that keeping track of all possible deallocations yourself can
cause huge code structure problems.

I’d have to disagree with both of those assertions. The #1 source of
mistakes I see, both in my own coding and in the enormous (3M+ lines of
code) multitier database app I’m on the team for at work, is null pointer
dereferences. (Calling things before they’ve been initialized.) #2 is
off-by-one errors, and it’s a pretty distant second. Manual resource
deallocation problems is probably somewhere in the top 10, but it’s
certainly not #1. (Of course, YMMV in a language that doesn’t support
try…finally. That makes things so much easier…)

As for “keeping track of all possible deallocations yourself,” why in the
world would you want to do that? That’s not a cause of code structure
problems, it’s a symptom of it. If your code isn’t already written in such
a way that every object has one and only one authoritative owner at any
point in the execution path, you deserve all the memory management headaches
you get.

There are basically only four things that can own an object:

  1. A function. The object is created locally. Make sure you free it when
    you leave. C++ makes this particularly easy by letting you allocate the
    object on the stack, and then the compiler calls the destructor once it
    drops out of scope. (Just make sure that you don’t stack-allocate any
    object you’re going to hand to another object! Create those on the heap.)
  2. A unit (namespace.) This is also known as a global object. Globals are
    problematic anyway, and if you’re using them you deserve all the headaches
    that come with them. The one exception is singleton objects which need to
    be accessible to pretty much the entire program. Thing is, singletons
    generally don’t need to be freed anyway, since they remain in use until the
    program quits, at which time the OS reclaims the memory.
  3. Another object, as a sub-object. My Person class has two Arm objects,
    each of which has a Hand object, each of which has five Finger objects.
    Make sure that the destructor handles it. If your parent object has
    mutator functions that allow you to reassign a sub-object, make sure that
    the mutator handles the existing one. (It should either free it directly or
    does something with reference counting to make sure it’s safe to free it.)
  4. A collection. The collection should explicitly either own its objects
    or not own them. If it owns them, it frees them automatically as part of
    its own destructor. Make sure that gets called. If it doesn’t, then the
    object is owned by one of the other 3 owners.

I’ve been coding for years in Delphi with manual memory management only,
(for objects at least; it uses compiler magic to handle dynamic arrays and
strings,) following these guidelines, and only once had any problems with
lost memory. Turns out I thought I was handing something to a collection
that owned the objects, but it didn’t. Drove me up the wall for a few days,
then someone suggested using the memory manager’s built-in functionality to
track it down. Took me about an hour and a half to fix it. And I’ve never
had to deal with the memory and code bloat of smart pointers or the
performance issues of a manual garbage collector. It’s not really hard at
all to keep track of your memory once you internalize the principles of
every object having only one owner, and every owner being one of those 4
categories I mentioned.

Really, if you’re writing unmanaged code, learn to clean up your own
memory. Any other way produces slow, bloated code and can also end up
hiding more subtle, insidious errors.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Quite right about the 4 categories (although I count collections as
objects themselves, usually, but the meaning is the same). The key, I
think, is understanding ownership, what it is and what it isn’t, the
difference between a strong reference and a weak reference (feel free
to look up those two terms on Wikipedia!).

For example, in a circular linked list (deliberately picking the kind
of thing that would give reference counting a fit), a node does not
have ownership of the node pointed at by it’s “next” pointer. The
linked list as a whole is the owner of those. The fact that they
point to each others is just part of the mechanics of how a circular
linked list works. That’s why making those pointers into shared_ptr is
a mistake: shared_ptr should only be used for owning pointers
(strong references).

Another example is in a tree structure, children nodes that have
pointers pointing back at their parents. These are not strong
references, they are weak references. You can easily tell in that
case, because it very rarely make sense for a child to outlive it’s
parent, except in very specific cases.

The question you could ask yourself is this: when you see a pointer,
would it ever make sense to free the memory it’s pointing at when
the pointer goes away? If it never makes sense, it’s a weak
reference. If it always make sense, it’s a strong reference with
single ownership (the best kind!). If it just sometimes make sense,
then it’s still a strong reference, but with possibly shared
ownership.

I’ve been coding for years in Delphi with manual memory management only, (for objects at least; it uses compiler magic to handle dynamic arrays and strings,) following these guidelines, and only once had any problems with lost memory. Turns out I thought I was handing something to a collection that owned the objects, but it didn’t. Drove me up the wall for a few days, then someone suggested using the memory manager’s built-in functionality to track it down. Took me about an hour and a half to fix it. And I’ve never had to deal with the memory and code bloat of smart pointers or the performance issues of a manual garbage collector. It’s not really hard at all to keep track of your memory once you internalize the principles of every object having only one owner, and every owner being one of those 4 categories I mentioned.

The smart pointers in C++ basically serve as a tag to remind you (and
the compiler) whether that function will take ownership or not. For
example, here’s a function that doesn’t take ownership:

void do_stuff(Foo& thefoo);

It might modify it (or not, if you put “const” in front of “Foo&”),
but it won’t keep it. It is possible to put that reference in a new
object, but it would be bad form (just like you can make C++
references be NULL, but it’s reasonable to say “hey, don’t do that,
it’s evil!”). If you want it to be possible to call the function
without an object, a “Foo*” could do, but it leaves it a bit
ambiguous. I have been known to write myself a “dumb_ptr”, very
similar to scoped_ptr, but without the “delete”, to indicate that
you’re not supposed to keep it. :slight_smile:

The following is an example that takes ownership:

void do_stuff(const shared_ptr& thefoo);

The fact that it’s specifically asking for a shared_ptr is indicative
that it wants to be involved with ownership.

By the way, if you do C++, it’s useful to think of the standard
containers as always owning what they contain. When you do something
like “vector<Foo*>”, the vector owns the Foo*, but the thing is,
that’s just not very important, owning the pointer. What you really
care about is who owns the Foo itself! That’s why saying
"vector<shared_ptr >" versus “vector<Foo&>” (or my
"vector<dumb_ptr >") is useful.

I also kind of object to equating smart pointers with memory and code
bloat. Using intrusive_ptr can gives you the same efficiency as coding
reference counting by yourself (pass by const reference, not by value,
to avoid tweaking the refcount all the time, after that you’re good),
and scoped_ptr has exactly the same memory and code footprint as
using a normal pointer and deleting it yourself, except it never
forgets (and the compiler knows that it shouldn’t be copied around,
and prevents compilation of erroneous code) . And my dumb_ptr, well,
is absolutely the same as a regular pointer (except it doesn’t support
automatically casting itself to a raw pointer, to avoid erroneous
code, again) :slight_smile:

Smart pointers aren’t smart in your place, you still have to think
about who owns what, it’s just putting down your thinking in the code,
so that other developers and the compiler know what you really
meant.On Tue, Jan 27, 2009 at 3:19 PM, Mason Wheeler wrote:


http://pphaneuf.livejournal.com/