Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SGCL - Garbage Collector for C++

85 views
Skip to first unread message

Sebastian Nibisz

unread,
Feb 28, 2008, 9:09:59 AM2/28/08
to
SGCL is precise, parallel garbage collection library for C++ (at this time
for Windows 32/64 only). SGCL is free software published under University of
Illinois/NCSA Open Source License.

Get it at:
http://sourceforge.net/projects/sgcl/

Regards
Sebastian Nibisz

mosfet

unread,
Feb 28, 2008, 9:13:51 AM2/28/08
to
Sebastian Nibisz a écrit :

If you need garbage collection you should try D language.

Linonut

unread,
Feb 28, 2008, 9:49:53 AM2/28/08
to
* Sebastian Nibisz peremptorily fired off this memo:

> SGCL is precise, parallel garbage collection library for C++ (at this time
> for Windows 32/64 only).

Ridiculous.

> SGCL is free software published under University of
> Illinois/NCSA Open Source License.

--
When the PC was launched, people knew it was important.
-- Bill Gates

Sebastian Nibisz

unread,
Feb 28, 2008, 9:59:28 AM2/28/08
to
> If you need garbage collection you should try D language.

The D language doesn't have the parallel garbage collector.

Regards
Sebastian Nibisz

Christopher

unread,
Feb 28, 2008, 10:57:24 AM2/28/08
to

Garbage collection is for lazy rich folks who can't be bothered to
take out their own trash.

Sebastian Nibisz

unread,
Feb 28, 2008, 11:07:24 AM2/28/08
to
> Garbage collection is for lazy rich folks who can't be bothered to
> take out their own trash.

It's funny.

Sebastian Nibisz

unread,
Feb 28, 2008, 11:26:12 AM2/28/08
to
> Garbage collection is for lazy rich folks who can't be bothered to
> take out their own trash.

struct node
{
node* next;
};

node* root = new node;
node* n = root;

for (int x = 0; x < 1000000; ++x)
{
n = n->next = new node;
}

How to release memory?

Alberto Bignotti

unread,
Feb 28, 2008, 11:58:06 AM2/28/08
to
node* root = new node;
node* n = root;

for (int x = 0; x < 10; ++x)


{
n = n->next = new node;

n->next = 0;
}

n=root;
while(n){
root=n;
n=n->next;
delete root;
}

is that 6 lines too much for you?
if your reply is yes then use a GC.
Be happy.

"Sebastian Nibisz" <EB...@poczta.onet.pl> ha scritto nel messaggio
news:fq6nba$rae$1...@inews.gazeta.pl...

Erik Wikström

unread,
Feb 28, 2008, 11:58:38 AM2/28/08
to

A recursive function?

--
Erik Wikström

Phil Endecott

unread,
Feb 28, 2008, 12:11:56 PM2/28/08
to

std::list<>
or boost::intrusive::list<>
or struct node { smart_pointer<node> next; };
or explicit destruction as Alberto described
or allocation from a pool which is all deallocated together
or garbage collection.

All have their advantages and disadvantages. Personally I'm happy with
std::list 99% of the time. I'm actually quite curious to know what sort
of applications or users use garbage collection in C++, but I fear that
it's the sort of discussion that can deteriorate....


Phil.

James Kanze

unread,
Feb 28, 2008, 12:22:00 PM2/28/08
to

> > struct node
> > {
> > node* next;
> > };

> > How to release memory?

> A recursive function?

:-).

Smart pointers. We all know that boost::shared_ptr is the
answer to all questions concerning pointers. So just replace
all of the pointers with boost::shared_ptr< node >.

Of course, this problem does have a fairly simple solution.
Most memory management problems do. It's just that it's not
always the same solution, so you have to do considerable
analysis to find it. I use the Boehm collector in new projects,
and it saves development time.

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Marcel Müller

unread,
Feb 28, 2008, 12:21:47 PM2/28/08
to
Sebastian Nibisz schrieb:

> struct node
> {
> node* next;
> };
>
> node* root = new node;
> node* n = root;
>
> for (int x = 0; x < 1000000; ++x)
> {
> n = n->next = new node;
> }
>
> How to release memory?

struct node
{ // content...
};

std::slist<boost::shared_ptr<node> > ?


or


struct node
{ boost::shared_ptr<node> next;
};


or if you look for very high performant solutions try
boost::intrusive_ptr which allows very small memory footprints of your
nodes because no additional heap objects are allocated at all.


In fact the only domain of GC solutions are complex data structures with
many cyclic references and without a parent child relation.


Marcel

Sebastian Nibisz

unread,
Feb 28, 2008, 12:36:04 PM2/28/08
to
> or
>
> struct node
> { boost::shared_ptr<node> next;
> };

{


for (int x = 0; x < 1000000; ++x)
{

n = n->next = shared_ptr<node>(new node);
}
} // <- STACK OVERFLOW


rgds
Sebastian Nibisz

Thomas J. Gritzan

unread,
Feb 28, 2008, 12:36:38 PM2/28/08
to
Erik Wikström schrieb:

Stack overflow?

--
Thomas
http://www.netmeister.org/news/learn2quote.html
To iterate is human, to recurse divine.
-L. Peter Deutsch

Phil Endecott

unread,
Feb 28, 2008, 1:25:28 PM2/28/08
to
Sebastian Nibisz wrote:
>> or
>>
>> struct node
>> { boost::shared_ptr<node> next;
>> };
>
> {
> for (int x = 0; x < 1000000; ++x)
> {
> n = n->next = shared_ptr<node>(new node);
> }
> } // <- STACK OVERFLOW

Why?

Jeff Schwab

unread,
Feb 28, 2008, 1:44:14 PM2/28/08
to

It's hard to guess why you would allocate nodes that way in the first place.

Sebastian Nibisz

unread,
Feb 28, 2008, 1:49:03 PM2/28/08
to
>> {
>> for (int x = 0; x < 1000000; ++x)
>> {
>> n = n->next = shared_ptr<node>(new node);
>> }
>> } // <- STACK OVERFLOW
>
> Why?

{
shared_ptr<node> root(new node);
shared_ptr<node> n(root);

for (int x = 0; x < 1000000; ++x)
{
n = n->next = shared_ptr<node>(new node);
}

} // <- recursive destruction (root)

rgds
Sebastian Nibisz

Sebastian Nibisz

unread,
Feb 28, 2008, 2:19:52 PM2/28/08
to
> for (int x = 0; x < 10; ++x)
> {
> n = n->next = new node;
> n->next = 0;
> }
>
> n=root;
> while(n){
> root=n;
> n=n->next;
> delete root;
> }

Ok. What if there is a cyclical list?

node* root = new node;
node* n = root;

node* r_n;

int r = rand() % 10;

for (int x = 0; x < 10; ++x)
{
n = n->next = new node;

if (x == r)
{
r_n = n;
}
}

n->next = r_n;

Sebastian Nibisz

unread,
Feb 28, 2008, 2:35:15 PM2/28/08
to
>> struct node
>> {
>> node* next;
>> };
>>
>> node* root = new node;
>> node* n = root;
>>
>> for (int x = 0; x < 1000000; ++x)
>> {
>> n = n->next = new node;
>> }
>>
>> How to release memory?
>
> It's hard to guess why you would allocate nodes that way in the first
> place.

The parent must know the child.

rgds
Sebastian Nibisz

James Kanze

unread,
Feb 28, 2008, 4:47:19 PM2/28/08
to
On Feb 28, 7:25 pm, Phil Endecott <spam_from_usenet_0...@chezphil.org>
wrote:
> Sebastian Nibisz wrote:
> >> or

> Why?

You're kidding us, right?

Eric was obviously being facious with his suggestion, since it
obviously wouldn't work; I can't imagine anyone not spotting the
problem immediately. The trick about shared_ptr, here, of
course, is that you don't see the recursion, so you may not
realize that you have the same problem until someone explicitly
asks what will happen.

It's really pretty rare that you can recurse 1000000 times
without the stack overflowing.

James Kanze

unread,
Feb 28, 2008, 4:54:00 PM2/28/08
to
On Feb 28, 6:11 pm, Phil Endecott <spam_from_usenet_0...@chezphil.org>
wrote:

> > struct node
> > {
> > node* next;
> > };

> > How to release memory?

Not really. There are those of us who are paid to produce
working code as inexpensively as possible. Garbage collection
saves some work in some specific cases (which do occur fairly
frequently, even if they don't represent the majority of dynamic
allocations), so we use it. Not doing so would be
irresponsible, from a professional point of view---something
like using <generic.h> instead of templates.

Naturally, of course:

-- objects with value semantics shouldn't be allocated
dynamically to begin with, so garbage collection won't
affect them,

-- even more obviously, the same thing holds for RAII
mangagers,

-- and generally, entity objects should manage their own
lifetimes---although using garbage collection here does
improve type safety, and allows catching some errors
(dangling pointers).

But there will usually be a few odd objects which don't fit into
one of the above categories, and garbage collection means one
less thing to code when using them (and the detection of
dangling pointers for entity objects isn't to be sneezed at if
you need robustness).

Ioannis Vranos

unread,
Feb 28, 2008, 5:15:09 PM2/28/08
to Sebastian Nibisz

Sounds like interesting stuff for anyone who wants to use GC in his/her
applications.

The thread shouldn't turn out to the flame "Do we need garbage
collection"? Anyone that can afford it in his/her applications and wants
to, he/she may use it.

Ioannis Vranos

unread,
Feb 28, 2008, 5:15:37 PM2/28/08
to

Sounds like interesting stuff for anyone who wants to use GC in his/her

Alf P. Steinbach

unread,
Feb 28, 2008, 5:16:05 PM2/28/08
to
* James Kanze:

> On Feb 28, 7:25 pm, Phil Endecott <spam_from_usenet_0...@chezphil.org>
> wrote:
>> Sebastian Nibisz wrote:
>>>> or
>
>>>> struct node
>>>> { boost::shared_ptr<node> next;
>>>> };
>
>>> {
>>> for (int x = 0; x < 1000000; ++x)
>>> {
>>> n = n->next = shared_ptr<node>(new node);
>>> }
>>> } // <- STACK OVERFLOW
>
>> Why?
>
> You're kidding us, right?
>
> Eric was obviously being facious with his suggestion, since it
> obviously wouldn't work; I can't imagine anyone not spotting the
> problem immediately. The trick about shared_ptr, here, of
> course, is that you don't see the recursion, so you may not
> realize that you have the same problem until someone explicitly
> asks what will happen.
>
> It's really pretty rare that you can recurse 1000000 times
> without the stack overflowing.

Huh?


Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Phil Endecott

unread,
Feb 28, 2008, 7:08:01 PM2/28/08
to
James Kanze wrote:
> On Feb 28, 7:25 pm, Phil Endecott <spam_from_usenet_0...@chezphil.org>
> wrote:
>> Sebastian Nibisz wrote:
>>>> or
>
>>>> struct node
>>>> { boost::shared_ptr<node> next;
>>>> };
>
>>> {
>>> for (int x = 0; x < 1000000; ++x)
>>> {
>>> n = n->next = shared_ptr<node>(new node);
>>> }
>>> } // <- STACK OVERFLOW
>
>> Why?
>
> You're kidding us, right?

James, that's pretty rude. I know this is usenet but I'd really
appreciate if if you could moderate the way you express yourself. I am
not "kidding you" when I say that I did not spot this problem, which is
why I asked "Why?". I have learnt something new and interesting this
evening. Why you had to chime in with that patronising phrase is beyond me.

Goodbye.

Sam

unread,
Feb 28, 2008, 7:53:02 PM2/28/08
to
Sebastian Nibisz writes:

It's true. If you do not have the skills and the know-how to keep track of
your own objects, and manage their lifetime, you have no business writing
mission-critical, business software.


Sam

unread,
Feb 28, 2008, 7:55:25 PM2/28/08
to
Sebastian Nibisz writes:

>> for (int x = 0; x < 10; ++x)
>> {
>> n = n->next = new node;
>> n->next = 0;
>> }
>>
>> n=root;
>> while(n){
>> root=n;
>> n=n->next;
>> delete root;
>> }
>
> Ok. What if there is a cyclical list?

Use your brain, and add two lines of code to the above fragment, making it
work for cyclical lists.

No, I'm not going to show you how to do it. I'm not sure you'll be able to
understand it.

Sam

unread,
Feb 28, 2008, 7:59:01 PM2/28/08
to
James Kanze writes:

> On Feb 28, 5:58 pm, Erik Wikström <Erik-wikst...@telia.com> wrote:
>> On 2008-02-28 17:26, Sebastian Nibisz wrote:
>
>> >> Garbage collection is for lazy rich folks who can't be
>> >> bothered to take out their own trash.
>
>> > struct node
>> > {
>> > node* next;
>> > };
>
>> > node* root = new node;
>> > node* n = root;
>
>> > for (int x = 0; x < 1000000; ++x)
>> > {
>> > n = n->next = new node;
>> > }
>
>> > How to release memory?
>
>> A recursive function?
>
> :-).
>
> Smart pointers. We all know that boost::shared_ptr is the
> answer to all questions concerning pointers. So just replace
> all of the pointers with boost::shared_ptr< node >.

No, please, not this horrible, stinking monstrosity called "Boost". The
other day I actually had the misfortune of looking how shared_ptr is
implemented, and nearly lost my lunch. Utterly clueless, brainless design. I
ended up coding my own version of shared_ptr, and benchmarked it 15% faster
than Boost's disgusting code.

Sebastian Nibisz

unread,
Feb 28, 2008, 8:49:12 PM2/28/08
to
I am impressed by your intelligence.

Sam

unread,
Feb 28, 2008, 9:06:29 PM2/28/08
to
Sebastian Nibisz writes:

> I am impressed by your intelligence.

You should be. You can't even manage the task of quoting the message you're
replying to, so that others actually may have a hint as to what in blazes
you're yammering about.

Jeff Schwab

unread,
Feb 28, 2008, 11:38:56 PM2/28/08
to

Sorry, I meant why not use a standard container to manage the nodes'
lifetimes? The slist mentioned elsewhere on this thread was a
reasonable suggestion, if std::list is too heavy.

Jeff Schwab

unread,
Feb 29, 2008, 12:05:04 AM2/29/08
to
Alf P. Steinbach wrote:
> * James Kanze:
>> On Feb 28, 7:25 pm, Phil Endecott <spam_from_usenet_0...@chezphil.org>
>> wrote:
>>> Sebastian Nibisz wrote:
>>>>> or
>>
>>>>> struct node
>>>>> { boost::shared_ptr<node> next;
>>>>> };
>>
>>>> {
>>>> for (int x = 0; x < 1000000; ++x)
>>>> {
>>>> n = n->next = shared_ptr<node>(new node);
>>>> }
>>>> } // <- STACK OVERFLOW
>>
>>> Why?
>>
>> You're kidding us, right?
...

>>
>> It's really pretty rare that you can recurse 1000000 times
>> without the stack overflowing.
>
> Huh?

I'm not sure it's obvious until you're been looking at it for a few
minutes, but given a program like the following:

#include <tr1/memory>

using std::tr1::shared_ptr;

struct node {
shared_ptr<node> next;
};

int main() {


shared_ptr<node> root(new node);
shared_ptr<node> n(root);

for (int x = 0; x < 1000000; ++x) {


n = n->next = shared_ptr<node>(new node);
}
}

When the "root" shared_ptr goes out of scope, the first node's reference
count goes to zero. root's destructor therefore deletes the first node,
causing the destructor of root->next to be invoked. That destructor
sees the reference count of the second node become zero, and so deletes
the second node, causing root->next->next to be invoked. And so on...

A better approach, IMHO, would be to let a factory allocate the nodes,
preferably as elements of a std::list<node>. The factory's destructor
(the list's, really) can make sure the memory is freed.

Alf P. Steinbach

unread,
Feb 29, 2008, 12:34:59 AM2/29/08
to
* Jeff Schwab:

Thanks. I didn't see that. Blind on both eyes! :-)

> A better approach, IMHO, would be to let a factory allocate the nodes,
> preferably as elements of a std::list<node>. The factory's destructor
> (the list's, really) can make sure the memory is freed.

Yup.

James Kanze

unread,
Feb 29, 2008, 4:50:45 AM2/29/08
to

> > It's funny.

And if you intentionally reject the use of a labor saving
device, and do something by hand which can easily be automated,
you're being professionally irresponsible.

James Kanze

unread,
Feb 29, 2008, 4:57:31 AM2/29/08
to

> >> > struct node
> >> > {
> >> > node* next;
> >> > };

> >> > How to release memory?

> >> A recursive function?

> > :-).

Hmmm. Apparently some one else who just doesn't understand, and
missed the whole point. Mainly that any smart pointer here will
cause a core dump.

FWIW: in the limited contexts where reference counted pointers
are appropriate, I also use my own. Mainly because I wrote it
long before boost::shared_ptr existed; any advantages it
provides aren't worth the added effort of reinventing the wheel.
But since I do have it, and it is both safer and faster than
boost::shared_ptr for reference counted memory management, I
continue to use it.

Reinventing the wheel, of course, isn't professional; a
professional uses all of the available tools to develop the most
robust software at the lowest price. (Which, of course, means
using garbage collection when it's available and when it's the
appropriate solution---it's a tool, just like any other.)

Nick Keighley

unread,
Feb 29, 2008, 5:03:24 AM2/29/08
to
On 28 Feb, 14:49, Linonut <lino...@bollsouth.nut> wrote:
> * Sebastian Nibisz peremptorily fired off this memo:

> > SGCL is precise, parallel garbage collection library for C++ (at this time
> > for Windows 32/64 only).
>

> Ridiculous.

why?

<snip>

--
Nick Keighley

James Kanze

unread,
Feb 29, 2008, 5:05:48 AM2/29/08
to
On Feb 29, 6:05 am, Jeff Schwab <j...@schwabcenter.com> wrote:
> Alf P. Steinbach wrote:
> > * James Kanze:
> >> On Feb 28, 7:25 pm, Phil Endecott <spam_from_usenet_0...@chezphil.org>
> >> wrote:
> >>> Sebastian Nibisz wrote:
> >>>>> or

> >>>>> struct node
> >>>>> { boost::shared_ptr<node> next;
> >>>>> };

> >>>> {
> >>>> for (int x = 0; x < 1000000; ++x)
> >>>> {
> >>>> n = n->next = shared_ptr<node>(new node);
> >>>> }
> >>>> } // <- STACK OVERFLOW

> >>> Why?

> >> You're kidding us, right?
> ...

> >> It's really pretty rare that you can recurse 1000000 times
> >> without the stack overflowing.

> > Huh?

> I'm not sure it's obvious until you're been looking at it for
> a few minutes,

It depends on context. Given the above snippet of code, it's
not at all obvious that there is a recursion, and I expect it
would slip through most code reviews. Given the fact that this
code appeared as a response to an ironical suggestion to use
recursion, one might be stimulated to think about it, and
recognize the fact. Given that someone had already said "stack
overflow", I'm rather surprised that Alf missed it---he doesn't
usually miss these sort of things.

[...]


> A better approach, IMHO, would be to let a factory allocate
> the nodes, preferably as elements of a std::list<node>. The
> factory's destructor (the list's, really) can make sure the
> memory is freed.

There are several possible approches that work well. The one
that requires the least explicit coding on the part of the
developer is garbage collection, which was, I presume, the
intent of the person who first posted this example.

IMHO, the real point here is that unless you're using garbage
collection, different situations require different solutions.
That means additional analysis and coding. Not necessarily a
lot, but each little bit adds up.

James Kanze

unread,
Feb 29, 2008, 5:16:25 AM2/29/08
to
On Feb 29, 1:08 am, Phil Endecott <spam_from_usenet_0...@chezphil.org>
wrote:

> James Kanze wrote:
> > On Feb 28, 7:25 pm, Phil Endecott <spam_from_usenet_0...@chezphil.org>
> > wrote:
> >> Sebastian Nibisz wrote:
> >>>> or

> >>>> struct node
> >>>> { boost::shared_ptr<node> next;
> >>>> };

> >>> {
> >>> for (int x = 0; x < 1000000; ++x)
> >>> {
> >>> n = n->next = shared_ptr<node>(new node);
> >>> }
> >>> } // <- STACK OVERFLOW

> >> Why?

> > You're kidding us, right?

> James, that's pretty rude.

I'm sorry, but it's frustrating. Somewhat upthread, someone
said "recursion", doubtlessly ironically, since I do presume
that everyone would realize thatexplicitly recursing 1000000
times was a bad idea. Given the fact that the use of shared_ptr
was suggested in that context, it seems obviously just an
extention of the irony to me---let's hide the recursion.

Without this context, frankly, I don't think many people would
spot the problem in code review. Given the context, however, I
do find it very surprising that people whom I know to be
competent do not see the problem immediately. It makes the
irony somewhat ineffective (although it does strengthen the
argument against unthinking use of shared_ptr). Which is, of
course, frustrating to those of us who are trying to use it.

> I know this is usenet but I'd really appreciate if if you
> could moderate the way you express yourself. I am not
> "kidding you" when I say that I did not spot this problem,
> which is why I asked "Why?". I have learnt something new and
> interesting this evening. Why you had to chime in with that
> patronising phrase is beyond me.

Because people not realizing the problem, in context, spoils the
rhetorical effect of the irony. Sorry. But as soon as Erik
mentionned recursion, it occured to me that I could "hide" it in
a shared_ptr, and that since shared_ptr was often suggested as
an alternative to garbage collection. Then you and Alf go and
spoil the effect (and I know both of you to be extremely
competent programmers) by missing the irony.

Sam

unread,
Feb 29, 2008, 7:10:15 AM2/29/08
to
James Kanze writes:

> On Feb 29, 1:53 am, Sam <s...@email-scan.com> wrote:
>> Sebastian Nibisz writes:
>> >> Garbage collection is for lazy rich folks who can't be
>> >> bothered to take out their own trash.
>
>> > It's funny.
>
>> It's true. If you do not have the skills and the know-how to
>> keep track of your own objects, and manage their lifetime, you
>> have no business writing mission-critical, business software.
>
> And if you intentionally reject the use of a labor saving
> device, and do something by hand which can easily be automated,
> you're being professionally irresponsible.

And you'll be even more professionally irresponsible if you use a so-called
"labor saving device" as merely a crutch to support your own lack of
experience and know-how, rather than taking the time, learning, and
educating yourself on how to do it right in the first place, instead of
relying on mis-designed spaghetti code to pull you nuts out of the fire.


Sam

unread,
Feb 29, 2008, 7:11:51 AM2/29/08
to
James Kanze writes:

Apparently someone else here who just doesn't understand that the problem
here is not with using a smart pointer, but with mis-using it.

Richard Herring

unread,
Feb 29, 2008, 7:23:34 AM2/29/08
to
In message <cone.1204246382...@commodore.email-scan.com>,
Sam <s...@email-scan.com> writes

>Sebastian Nibisz writes:
>
>>> Garbage collection is for lazy rich folks who can't be bothered to
>>> take out their own trash.
>> It's funny.
>
>It's true. If you do not have the skills and the know-how to keep track
>of your own objects, and manage their lifetime,

... or if you think garbage collection is about lifetime management ...

>you have no business writing mission-critical, business software.

--
Richard Herring

James Kanze

unread,
Feb 29, 2008, 11:20:37 AM2/29/08
to

> >> > It's funny.

Doing it right is doing it in the most effective and
maintainable way possible. Not inventing a lot of make-work
just to be able to bill extra time.

James Kanze

unread,
Feb 29, 2008, 11:26:27 AM2/29/08
to
On Feb 29, 1:23 pm, Richard Herring <junk@[127.0.0.1]> wrote:
> In message <cone.1204246382.29097.21741....@commodore.email-scan.com>,
> Sam <s...@email-scan.com> writes

> >Sebastian Nibisz writes:

> >>> Garbage collection is for lazy rich folks who can't be bothered to
> >>> take out their own trash.
> >> It's funny.

> >It's true. If you do not have the skills and the know-how to
> >keep track of your own objects, and manage their lifetime,

> ... or if you think garbage collection is about lifetime
> management ...

Agreed. If you don't understand your tool, you won't be able to
use it correctly. And garbage collection has nothing to do with
lifetime management; it only intervenes in memory management.
(It's also useful for catching dangling pointers. If the object
is dead, you can mark it dead, and be sure that that mark won't
be overwritten as long as anyone has a pointer to the object.)

Of course, a lot of objects don't need any particular handling
when you're through with them. Once your analysis has
determined those, with garbage collection, you're through with
them; without, you've still got to write the code to clean up
the memory.

Alf P. Steinbach

unread,
Feb 29, 2008, 12:27:37 PM2/29/08
to
* James Kanze:

> Given that someone had already said "stack
> overflow", I'm rather surprised that Alf missed it---he doesn't
> usually miss these sort of things.

I think we rely much more on simple pattern matching (and hence expectations and
previous experience) than reasoning.

Not sure if you've read David Brin's uplift trilogy, but there's this scene
where two guys cross the wilderness and one of them plants a lot of false
evidence to convince the other there's someone shadowing them. However, the
other guy doesn't even notice all this fake evidence, because it's so bad, so
fake, so atypical, that it doesn't even reach his higher cognitive functions for
consideration... It's automatically filtered out, because it doesn't make sense
even at the lowest level of external input processing.

After some time, this other guy notices something the first one didn't, namely
that apparently there /is/ someone shadowing them.


Cheers,

- Alf (reserving The Right 2 B SOTU :-) )

James Kanze

unread,
Feb 29, 2008, 2:27:30 PM2/29/08
to
On Feb 29, 6:27 pm, "Alf P. Steinbach" <al...@start.no> wrote:
> * James Kanze:

> > Given that someone had already said "stack
> > overflow", I'm rather surprised that Alf missed it---he doesn't
> > usually miss these sort of things.

> I think we rely much more on simple pattern matching (and
> hence expectations and previous experience) than reasoning.

> Not sure if you've read David Brin's uplift trilogy, but
> there's this scene where two guys cross the wilderness and one
> of them plants a lot of false evidence to convince the other
> there's someone shadowing them. However, the other guy
> doesn't even notice all this fake evidence, because it's so
> bad, so fake, so atypical, that it doesn't even reach his
> higher cognitive functions for consideration... It's
> automatically filtered out, because it doesn't make sense even
> at the lowest level of external input processing.

I'm not familiar with it, but yes. Context certainly plays a
large role; we normally only see things we're looking for, and
what we look for depends to a large degree on what we expect to
find.

I'll admit that without the comment about "recursion"
immediately up-thread, I probably wouldn't have spotted it
either. However, that word triggered something in my mind, a
comment by Hans Boehm, I think, to the effect that manual memory
management can create the same pauses people complain about in
garbage collection. With a long list or a complex tree being
his example, where destruction of the root triggers *recursive*
destruction of hundreds of thousands of elements. Without
that... (In other words, I'd already had the case explained to
me by a master.)

Ian Collins

unread,
Feb 29, 2008, 2:58:21 PM2/29/08
to
James Kanze wrote:
> On Feb 29, 1:10 pm, Sam <s...@email-scan.com> wrote:
>> James Kanze writes:
>
>>> And if you intentionally reject the use of a labor saving
>>> device, and do something by hand which can easily be automated,
>>> you're being professionally irresponsible.
>
>> And you'll be even more professionally irresponsible if you
>> use a so-called "labor saving device" as merely a crutch to
>> support your own lack of experience and know-how, rather than
>> taking the time, learning, and educating yourself on how to do
>> it right in the first place, instead of relying on
>> mis-designed spaghetti code to pull you nuts out of the fire.
>
> Doing it right is doing it in the most effective and
> maintainable way possible. Not inventing a lot of make-work
> just to be able to bill extra time.
>
Your problems begin when your maintenance task is to port the code to a
platform without GC support.....

--
Ian Collins.

Ian Collins

unread,
Feb 29, 2008, 3:01:22 PM2/29/08
to
James Kanze wrote:
>
> Of course, a lot of objects don't need any particular handling
> when you're through with them. Once your analysis has
> determined those, with garbage collection, you're through with
> them; without, you've still got to write the code to clean up
> the memory.
>
Until a later maintainer alters the object (or one that it includes) so
it does require particular handling when you're through with them. Then
the fun really begins.

--
Ian Collins.

Sam

unread,
Feb 29, 2008, 6:24:40 PM2/29/08
to
Richard Herring writes:

> In message <cone.1204246382...@commodore.email-scan.com>,
> Sam <s...@email-scan.com> writes
>>Sebastian Nibisz writes:
>>
>>>> Garbage collection is for lazy rich folks who can't be bothered to
>>>> take out their own trash.
>>> It's funny.
>>
>>It's true. If you do not have the skills and the know-how to keep track
>>of your own objects, and manage their lifetime,
>
> ... or if you think garbage collection is about lifetime management ...

Let me know when you figure out why, in Java, you have to throw all these
try/catch blocks around, every time you need to deal with files or sockets,
in order not to run out of available file descriptors.

So much for garbage collection.


James Kanze

unread,
Feb 29, 2008, 7:21:40 PM2/29/08
to

Or to a platform without C++ support... Or in my case, to a
platform without directories, or sockets, or files, or threads.
GC support is at least as widely available as threads or
sockets.

James Kanze

unread,
Feb 29, 2008, 7:25:55 PM2/29/08
to

How is garbage collection in any way relevant to that? Garbage
collection is concerned with memory management, not object
lifetime management. If you have to do something special when
an object's lifetime ends, then you have to do it. Garbage
collection or not. All garbage collection does is mean that you
don't have to worry about freeing the memory under the object,
and that you can implement code to catch errors in your lifetime
management---pointers to the object that are used after the
object is dead.

James Kanze

unread,
Feb 29, 2008, 7:29:32 PM2/29/08
to
On Mar 1, 12:24 am, Sam <s...@email-scan.com> wrote:
> Richard Herring writes:
> > In message <cone.1204246382.29097.21741....@commodore.email-scan.com>,

> > Sam <s...@email-scan.com> writes
> >>Sebastian Nibisz writes:

> >>>> Garbage collection is for lazy rich folks who can't be bothered to
> >>>> take out their own trash.
> >>> It's funny.

> >>It's true. If you do not have the skills and the know-how to keep track
> >>of your own objects, and manage their lifetime,

> > ... or if you think garbage collection is about lifetime management ...

> Let me know when you figure out why, in Java, you have to
> throw all these try/catch blocks around, every time you need
> to deal with files or sockets,

Because Java doesn't have local objects or destructors. Which
has nothing to do with garbage collection.

> in order not to run out of available file descriptors.

In Java, you use try/catch blocks, and in C++, you use
destructors. Garbage collection has nothing to do with the
issue.

Ian Collins

unread,
Feb 29, 2008, 8:05:16 PM2/29/08
to
James Kanze wrote:
> On Feb 29, 8:58 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>> James Kanze wrote:
>>> On Feb 29, 1:10 pm, Sam <s...@email-scan.com> wrote:
>>>> James Kanze writes:
>
>>>>> And if you intentionally reject the use of a labor saving
>>>>> device, and do something by hand which can easily be automated,
>>>>> you're being professionally irresponsible.
>
>>>> And you'll be even more professionally irresponsible if you
>>>> use a so-called "labor saving device" as merely a crutch to
>>>> support your own lack of experience and know-how, rather than
>>>> taking the time, learning, and educating yourself on how to do
>>>> it right in the first place, instead of relying on
>>>> mis-designed spaghetti code to pull you nuts out of the fire.
>
>>> Doing it right is doing it in the most effective and
>>> maintainable way possible. Not inventing a lot of make-work
>>> just to be able to bill extra time.
>
>> Your problems begin when your maintenance task is to port the
>> code to a platform without GC support.....
>
> Or to a platform without C++ support... Or in my case, to a
> platform without directories, or sockets, or files, or threads.
> GC support is at least as widely available as threads or
> sockets.
>
True, but there's plenty of embedded platforms with POSIX support where
garbage collection, even if available, would be acceptable.

If a platform didn't have threads or sockets, it would an unlikely
candidate for a port of an application that used them. Even if it was
chosen, being libraries with well documented interfaces, they could be
implemented, simulated or stubbed by any competent developer. You can't
make the same claim for GC!

--
Ian Collins.

Ian Collins

unread,
Feb 29, 2008, 8:09:21 PM2/29/08
to
James Kanze wrote:
> On Feb 29, 9:01 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>> James Kanze wrote:
>
>>> Of course, a lot of objects don't need any particular
>>> handling when you're through with them. Once your analysis
>>> has determined those, with garbage collection, you're
>>> through with them; without, you've still got to write the
>>> code to clean up the memory.
>
>> Until a later maintainer alters the object (or one that it
>> includes) so it does require particular handling when you're
>> through with them. Then the fun really begins.
>
> How is garbage collection in any way relevant to that? Garbage
> collection is concerned with memory management, not object
> lifetime management. If you have to do something special when
> an object's lifetime ends, then you have to do it. Garbage
> collection or not. All garbage collection does is mean that you
> don't have to worry about freeing the memory under the object,
> and that you can implement code to catch errors in your lifetime
> management---pointers to the object that are used after the
> object is dead.
>
My point, which appears to have been badly made, is that it is foolhardy
to rely on GC to clean up some objects but not others.

I don't object to the use of GC, provided it is used consistently
throughout a design.

--
Ian Collins.

Ian Collins

unread,
Feb 29, 2008, 8:16:30 PM2/29/08
to
Ian Collins wrote:
> True, but there's plenty of embedded platforms with POSIX support where
> garbage collection, even if available, would be acceptable.
>
Make that "*not* acceptable!

--
Ian Collins.

Sam

unread,
Feb 29, 2008, 9:11:47 PM2/29/08
to
James Kanze writes:

> On Mar 1, 12:24 am, Sam <s...@email-scan.com> wrote:
>> Richard Herring writes:
>> > In message <cone.1204246382.29097.21741....@commodore.email-scan.com>,
>> > Sam <s...@email-scan.com> writes
>

>> Let me know when you figure out why, in Java, you have to
>> throw all these try/catch blocks around, every time you need
>> to deal with files or sockets,
>
> Because Java doesn't have local objects or destructors. Which

Java most certainly has destructors. See java.lang.Object.finalize().

Java has local objects too. But that's going to be your homework assignment
for today.

> has nothing to do with garbage collection.

It has everything to do with garbage collection.

>
>> in order not to run out of available file descriptors.
>
> In Java, you use try/catch blocks, and in C++, you use
> destructors.

Whoooooooosh!!! Right over your head.

> Garbage collection has nothing to do with the
> issue.

You keep repeating this, but repeating something, over and over again, does
not necessarily make it true.

Sam

unread,
Feb 29, 2008, 9:22:44 PM2/29/08
to
James Kanze writes:

> On Feb 29, 9:01 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>> James Kanze wrote:
>
>> > Of course, a lot of objects don't need any particular
>> > handling when you're through with them. Once your analysis
>> > has determined those, with garbage collection, you're
>> > through with them; without, you've still got to write the
>> > code to clean up the memory.
>
>> Until a later maintainer alters the object (or one that it
>> includes) so it does require particular handling when you're
>> through with them. Then the fun really begins.
>
> How is garbage collection in any way relevant to that? Garbage
> collection is concerned with memory management, not object
> lifetime management.

You're making no sense.

If you separate the object destruction phase from the memory release phase,
then you must be asserting that you are going to be explicitly invoking the
object destruction phase, at some point, yourself, instead of relying on the
garbage collector on doing that.

But if that's what you're going to do, if you are going to be destroying
your objects yourself, then what exactly are you going to gain by not
freeing the memory, right then and there, instead of leaving it to the
garbage collector to free the memory at some later, indeterminate point?

> If you have to do something special when
> an object's lifetime ends, then you have to do it.

Bravo! You finally got it. If you're going to explicitly destroy the object,
then you're going to free the memory right than and there. To stop short
before doing that, and leaving it to the garbage collector, is absolutely
demented, and you gain absolutely nothing from doing that.

> Garbage
> collection or not.

If you're going to use a garbage collection model, it logically follows that
you're postponing object destruction/finalization until then. Because if
you're not -- if you're going to destroy and finalize the object yourself --
then you'll simply free the memory at the same time too, because by the
virtue of invoking the destructor, you are stating that no references to the
object remain, so you can free the memory right than and there.

Refusing to do that, and instead choosing to foist a completely unnecessary
garbage collection framework on your neck, in that situation, is completely
and utterly retarded.

And that's precisely why I wrote, right from the start, that garbage
collection is only for those who are too stupid to manage and keep track of
their objects, and their lifetime, themselves. Because if they do have
enough wits to keep track of their objects' lifetime, and invoke their
destructors at the appropriate time, they'll just release the memory at the
same time. We even have an operator for doing that. It's called "delete".

Who'da thunk it?


Alf P. Steinbach

unread,
Feb 29, 2008, 9:36:08 PM2/29/08
to
* Sam:

>
> If you separate the object destruction phase from the memory release
> phase, then you must be asserting that you are going to be explicitly
> invoking the object destruction phase, at some point, yourself, instead
> of relying on the garbage collector on doing that.
>
> But if that's what you're going to do, if you are going to be destroying
> your objects yourself, then what exactly are you going to gain by not
> freeing the memory, right then and there, instead of leaving it to the
> garbage collector to free the memory at some later, indeterminate point?

Mostly that this processing can be done at otherwise idle moments, or spread
over time instead of all at once (like when deleting some dynamic data structure).

It is of course not a free lunch.


Cheers, & hth.,

- Alf

Ian Collins

unread,
Feb 29, 2008, 10:06:16 PM2/29/08
to
Sam wrote:
> James Kanze writes:
>
>> On Mar 1, 12:24 am, Sam <s...@email-scan.com> wrote:
>>> Richard Herring writes:
>>> > In message <cone.1204246382.29097.21741....@commodore.email-scan.com>,
>>> > Sam <s...@email-scan.com> writes
>>
>>> Let me know when you figure out why, in Java, you have to
>>> throw all these try/catch blocks around, every time you need
>>> to deal with files or sockets,
>>
>> Because Java doesn't have local objects or destructors. Which
>
> Java most certainly has destructors. See java.lang.Object.finalize().
>
But that's not an automatic destructor in the C++ sense, is it?

--
Ian Collins.

Sam

unread,
Feb 29, 2008, 10:55:54 PM2/29/08
to
Ian Collins writes:

It is a destructor in the C++ sense as in "gets invoked before the object's
memory is released".

That's precisely the point I am making. Garbage collection's only benefit is
to clean up your objects when you can't keep track of their lifetime, and
must rely on the garbage collector to destroy the objects when they no
longer have any strong references. Because if you do have the discipline to
keep track of your objects, and destroy them when they're no longer needed,
you don't need any fscking garbage collector.

Sam

unread,
Feb 29, 2008, 10:58:58 PM2/29/08
to
Alf P. Steinbach writes:

> * Sam:
>>
>> If you separate the object destruction phase from the memory release
>> phase, then you must be asserting that you are going to be explicitly
>> invoking the object destruction phase, at some point, yourself, instead
>> of relying on the garbage collector on doing that.
>>
>> But if that's what you're going to do, if you are going to be destroying
>> your objects yourself, then what exactly are you going to gain by not
>> freeing the memory, right then and there, instead of leaving it to the
>> garbage collector to free the memory at some later, indeterminate point?
>
> Mostly that this processing can be done at otherwise idle moments, or spread
> over time instead of all at once (like when deleting some dynamic data structure).

And when your app does not have any idle moments, you end up running out of
memory.

<Splorf>

That actually happened at day job, last week. A tick data app ran out of
memory and crashed, because it kept chewing on the exchange's tick feed, and
had no spare cycles for the Java VM to run the garbage collector, and
release memory held my objects that were no longer in use.

Lots of fun that was.


I V

unread,
Feb 29, 2008, 11:46:20 PM2/29/08
to
On Fri, 29 Feb 2008 20:22:44 -0600, Sam wrote:
> James Kanze writes:
>
>> How is garbage collection in any way relevant to that? Garbage
>> collection is concerned with memory management, not object lifetime
>> management.
>
> You're making no sense.
>
> If you separate the object destruction phase from the memory release
> phase, then you must be asserting that you are going to be explicitly
> invoking the object destruction phase, at some point, yourself, instead
> of relying on the garbage collector on doing that.

GC is typically used with objects where the object destruction phase does
nothing. With these objects, you don't need to invoke the object
destruction phase, implicitly or explicitly, so you can just ignore it
and let the GC deal with the memory release phase. So the problem you're
talking about here doesn't arise.

I V

unread,
Feb 29, 2008, 11:51:11 PM2/29/08
to
On Fri, 29 Feb 2008 21:55:54 -0600, Sam wrote:
> That's precisely the point I am making. Garbage collection's only
> benefit is to clean up your objects when you can't keep track of their
> lifetime, and must rely on the garbage collector to destroy the objects
> when they no longer have any strong references. Because if you do have
> the discipline to keep track of your objects, and destroy them when
> they're no longer needed, you don't need any fscking garbage collector.

But if you don't particularly care when objects are deleted (which, when
the only resource an object uses is memory, you may be right not to care
about), then with a GC you don't need the discipline to keep track of
these objects. Which is good, because my discipline, at any rate, is
finite, and I would like to preserve it for those cases where it matters,
not those cases where it doesn't matter.

Kai-Uwe Bux

unread,
Mar 1, 2008, 12:14:14 AM3/1/08
to
Sam wrote:

> Ian Collins writes:
>
>> Sam wrote:
>>> James Kanze writes:
>>>
>>>> On Mar 1, 12:24 am, Sam <s...@email-scan.com> wrote:
>>>>> Richard Herring writes:
>>>>> > In message
>>>>> > <cone.1204246382.29097.21741....@commodore.email-scan.com>, Sam
>>>>> > <s...@email-scan.com> writes
>>>>
>>>>> Let me know when you figure out why, in Java, you have to
>>>>> throw all these try/catch blocks around, every time you need
>>>>> to deal with files or sockets,
>>>>
>>>> Because Java doesn't have local objects or destructors. Which
>>>
>>> Java most certainly has destructors. See java.lang.Object.finalize().
>>>
>> But that's not an automatic destructor in the C++ sense, is it?
>
> It is a destructor in the C++ sense as in "gets invoked before the
> object's memory is released".

Now, that is definitely _not_ a destructor in the C++ sense: according to
[3.8/4] it is possible to release or reuse memory without the destructor
getting invoked before.


> That's precisely the point I am making. Garbage collection's only benefit
> is to clean up your objects when you can't keep track of their lifetime,
> and must rely on the garbage collector to destroy the objects when they no

> longer have any strong references. [snip]

Are you sure that garbage collectors for C++ _destroy_ objects that become
unreachable? I was under the impression that they only reclaim the memory
and do not invoke the destructor.


Best

Kai-Uwe Bux

Ian Collins

unread,
Mar 1, 2008, 12:23:27 AM3/1/08
to
But how does a user know if an object has to be deleted, or whether it
can be left to the GC?

Languages like Java and JavaScript are unambiguous in this regard,
everything gets mopped up by the GC. The languages design requires GC.
It's the ambiguity with C++ I don't like, especially as C++ provides
language features that make GC an irrelevance.

For my own stuff, I pretty well use some form of smart pointer anywhere
I would have used a raw pointer, so I have no need for any form of GC.

--
Ian Collins.

Ioannis Vranos

unread,
Mar 1, 2008, 5:50:14 AM3/1/08
to


As all computers (from small embedded devices to large mainframes) are
getting more powerful along with their accompanying facilities, the
abstraction in programming will be increasing. Now we have those CLI
compliant GC frameworks (.NET, Mono etc), and I am pretty sure GC will
be common place sometime in the near future. Also we will see more
abstraction facilities, and less trade offs between space and speed. The
same applies for storage medium. For example consider mp3/ogg vs flac.
Now we have "mp3 players" with storage >1 GB.

This flame in this thread, reminds me other silly flames between C and
C++ advocates, with the C ones insisting that they can do whatever they
need without object oriented programming, templates etc.

Personally I think the near future will be with more abstraction (like
more templates, GC) and with less low-level facilities, since space and
run-time will have less importance, because of the more and more
powerful systems.

Chris Thomasson

unread,
Mar 2, 2008, 1:22:25 AM3/2/08
to

"Sebastian Nibisz" <EB...@poczta.onet.pl> wrote in message
news:fq6fbt$re3$1...@inews.gazeta.pl...
> SGCL is precise, parallel garbage collection library for C++ (at this time
> for Windows 32/64 only). SGCL is free software published under University
> of Illinois/NCSA Open Source License.
>
> Get it at:
> http://sourceforge.net/projects/sgcl/

How does this compare against a virtually zero-overhead PDR algorithm?

Chris Thomasson

unread,
Mar 2, 2008, 1:24:05 AM3/2/08
to
"Ian Collins" <ian-...@hotmail.com> wrote in message
news:62s7ifF2...@mid.individual.net...

Yeah. GC has it's problems... Here is just one of many:

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/5e9357a6fb746e5d

James Kanze

unread,
Mar 2, 2008, 8:57:36 AM3/2/08
to

I presume you mean "wouldn't be acceptable".

The issue is more complex than that. There are definitly
contexts where garbage collection wouldn't be acceptable; there
are even a lot of contexts where dynamic allocation isn't
acceptable. In such contexts, the "Posix" environment, per se,
typically isn't acceptable either, but...

Even critical systems have non critical parts, where both
classical Posix and garbage collection might be acceptable, and
there are systems which provide a Posix interface, or at least
something fairly similar, or possibly just a subset, but which
also provide additional guarantees which make them usable in
even the most critical contexts.

> If a platform didn't have threads or sockets, it would an
> unlikely candidate for a port of an application that used
> them. Even if it was chosen, being libraries with well
> documented interfaces, they could be implemented, simulated or
> stubbed by any competent developer. You can't make the same
> claim for GC!

Can't you? I'm not sure.

The real issue is what you're targetting with your
"portability". If you want to be portable to absolutely
everything, then of course, you can't count on garbage
collection, or Posix, or even 2's complement integers. That
level of portability is rarely relevent outside low level
libraries, however. At the other extreme, most of the places
I've worked lately have pretty much standardized on Solaris on
Sparc. They express the portability concerns differently: they
refuse to migrate to a new platform unless our existing code
base will work on it. The issue of migrating to Linux has
recently been very relevant, and GC is the least of our worries:
the Boehm collector works well on both platforms, although a lot
of the "Posix" functions have subtly different semantics. (And
of course, even under Solaris, the semantics of pthread_exit and
pthread_cancel are different depending on whether you compiled
with g++ or Sun CC.)

James Kanze

unread,
Mar 2, 2008, 9:07:29 AM3/2/08
to
On 1 mar, 11:50, Ioannis Vranos <ivra...@nospam.no.spamfreemail.gr>
wrote:
> Ian Collins wrote:
[...]

> As all computers (from small embedded devices to large mainframes) are
> getting more powerful along with their accompanying facilities, the
> abstraction in programming will be increasing. Now we have those CLI
> compliant GC frameworks (.NET, Mono etc), and I am pretty sure GC will
> be common place sometime in the near future.

Not "sometime in the near future". Today, it's actually rather
rare for a new development to not use GC. Partially, of course,
because most new developments do use either CLI or are in Java.
But many more serious, large scale developments do use C++ and
the Boehm collector. (In practice, Java doesn't really scale to
large scale developments, and CLI doesn't really work except on
Windows platforms, which aren't appropriate for large scale
developments.)

> Also we will see more abstraction facilities, and less trade
> offs between space and speed. The same applies for storage
> medium.

Yes. In a lot of applications, garbage collection is faster,
but typically, it uses more memory. Given the size of current
memories, this usually isn't an issue (but it could be in some
applications, particularly numeric simulations of large scale
physical phenomena, like weather).

> For example consider mp3/ogg vs flac. Now we have "mp3
> players" with storage >1 GB.

The question for something like a program used to predict the
weather is: do I use this extra memory to simplify memory
managment (which is already very, very simple, since the only
dynamic allocations are in a couple of very, very big arrays),
or do I use it to increase the density of points I'm plotting.

There are applications for which garbage collection isn't
appropriate. There are others---most business applications, for
example---where it represents a definite gain.

> This flame in this thread, reminds me other silly flames
> between C and C++ advocates, with the C ones insisting that
> they can do whatever they need without object oriented
> programming, templates etc.

In some cases, how true. That doesn't seem to be Ian's case,
however.

> Personally I think the near future will be with more
> abstraction (like more templates, GC) and with less low-level
> facilities, since space and run-time will have less
> importance, because of the more and more powerful systems.

In the near future, either C++ will support threads and garbage
collection, or it will become a niche language. That's really
independent of technical advantages of one or the other.

Currently, I see a lot of applications which are multithreaded,
but which shouldn't be. Realistically, if garbage collection
were part of the language, I expect that there will be a lot of
applications which use it where it's not appropriate. But just
as realistically, there are applications where one or the other
are appropriate, it's important that the language support them,
and the fact that something can be misused has never been an
argument against having it in the language.

James Kanze

unread,
Mar 2, 2008, 9:32:48 AM3/2/08
to
On 1 mar, 03:22, Sam <s...@email-scan.com> wrote:
> James Kanze writes:
> > On Feb 29, 9:01 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> >> James Kanze wrote:

> >> > Of course, a lot of objects don't need any particular
> >> > handling when you're through with them. Once your analysis
> >> > has determined those, with garbage collection, you're
> >> > through with them; without, you've still got to write the
> >> > code to clean up the memory.

> >> Until a later maintainer alters the object (or one that it
> >> includes) so it does require particular handling when you're
> >> through with them. Then the fun really begins.

> > How is garbage collection in any way relevant to that? Garbage
> > collection is concerned with memory management, not object
> > lifetime management.

> You're making no sense.

Either you're making no sense, or there's something about C++
you haven't understood.

> If you separate the object destruction phase from the memory
> release phase,

You don't change much. Currently, operator delete() and the
destructor are two different functions. The only link in the
current situation is that operator delete() will not normally be
called unless the destructor is called, so in a lot of cases,
you end up with destructors you wouldn't otherwise need.

> then you must be asserting that you are going to be explicitly
> invoking the object destruction phase, at some point,
> yourself, instead of relying on the garbage collector on doing
> that.

Certainly. The garbage collector never invokes object
destruction. The two things are separate concepts, and as such
should be disassociated.

> But if that's what you're going to do, if you are going to be
> destroying your objects yourself, then what exactly are you
> going to gain by not freeing the memory, right then and there,
> instead of leaving it to the garbage collector to free the
> memory at some later, indeterminate point?

A lot of objects don't have any real actions which have to be
carried out at the end of their lifetime. By design, in many
cases.

If we compare to Java, of course, garbage collection is much
less fundamental in C++. Our value objects are allocated on the
stack, and copied---since dynamic allocation isn't involved,
garbage collection is completely irrelevant. Entity objects
have a defined lifetime in both languages, and must be
explicitly disposed of (normally via the destructor in C++, and
some specific member function in Java)---the real problem with
them is ensuring that all interested parties are notified. In
such cases, garbage collection can help in debugging---you can
mark the object as invalid, and check the mark any time the
object is used, without any risk that the memory underlying the
object will be reused (and the mark overwritten) as long as
anyone still holds a pointer to the object. But it's purely a
defensive programming issue---in correct code, it shouldn't make
a difference. The fact remains, however, that there are other
types of objects. They're not numerous, but they do exist. In
my code, for example, I make some use of agents---small,
polymorphic objects without any real data (perhaps a pointer to
the object they operate on). Garbage collection is perfect for
them. And in other domains, there are complicated graph
structures---this is where garbage collection shines.

The usual way I've used garbage collection to date is to simply
replace operator new() with a function which calls gc_malloc(), and
operator delete() with one which calls gc_free(). And then
simply drop user defined destructors in classes like string, or
in my agents. It's less code which needs to be written. And
less code is always an improvement.

> > If you have to do something special when
> > an object's lifetime ends, then you have to do it.

> Bravo! You finally got it.

What do you mean, finally. This has always been a fundamental
concept for any competent programmer.

What you seem to be missing is the "if". In a lot of
applications, that if will usually be false, so the then part of
the sentence doesn't apply. Obviously, you need to do the
analysis to determine if it applies, but you need to do that
anyway, garbage collection or not---you need to know what to put
in the destructor before you write it. The difference when
using garbage collection is that if that analysis shows that
nothing really needs to be done (except memory management),
you're through. You've finished the job. Without garbage
collection, you've still got code to write.

In the contexts I've worked in, I've always had enough code to
write as is, without artificially creating the need to write
more.

> If you're going to explicitly destroy the object, then you're
> going to free the memory right than and there.

Maybe. You might want to keep it as long as there are pointers
to it, for error checking.

And of course, if you weren't going to explicitly destroy the
object, because disposing of the object had no significant
behavior, then garbage collection is a definite gain.

> To stop short before doing that, and leaving it to the garbage
> collector, is absolutely demented, and you gain absolutely
> nothing from doing that.

You gain robustness, when you need to explicitly dispose of the
object, and a lot less code to write, when you don't.

> > Garbage collection or not.

> If you're going to use a garbage collection model,

Garbage collection isn't a model. It's a tool. Maybe that's
where you're having problems with it.

> it logically follows that you're postponing object
> destruction/finalization until then. Because if you're not --
> if you're going to destroy and finalize the object yourself --
> then you'll simply free the memory at the same time too,
> because by the virtue of invoking the destructor, you are
> stating that no references to the object remain, so you can
> free the memory right than and there.

Disposing of an object is logically distinct from memory
management. The only constraint is that the object must be
disposed of before the memory is reused. Disposing of an
object---by that I mean explicitly terminating its lifetime,
with observable behavior linked to the end of lifetime---is a
design issue, and must always be addressed, at the design level,
regardless of the tool set used at a lower level. Memory
management is a much lower level issue.

> Refusing to do that, and instead choosing to foist a
> completely unnecessary garbage collection framework on your
> neck, in that situation, is completely and utterly retarded.

> And that's precisely why I wrote, right from the start, that
> garbage collection is only for those who are too stupid to
> manage and keep track of their objects, and their lifetime,
> themselves.

Which, of course, is false. No professional, today, would start
a new C++ application without considering garbage collection,
any more than he'd start it without considering templates, or
threads, or any other feature readily available. In many ways,
it's a lot like threads: you use it if it helps produce a
working application in less time, and you don't if it doesn't.
It costs nothing if you don't use it, and if it is appropriate,
using it reduces costs.

> Because if they do have enough wits to keep track of their
> objects' lifetime, and invoke their destructors at the
> appropriate time, they'll just release the memory at the same
> time. We even have an operator for doing that. It's called
> "delete".

As another example in this thread has shown, it isn't always
that simple.

James Kanze

unread,
Mar 2, 2008, 9:39:54 AM3/2/08
to
On 1 mar, 04:58, Sam <s...@email-scan.com> wrote:
> Alf P. Steinbach writes:
> > * Sam:

> >> If you separate the object destruction phase from the memory release
> >> phase, then you must be asserting that you are going to be explicitly
> >> invoking the object destruction phase, at some point, yourself, instead
> >> of relying on the garbage collector on doing that.

> >> But if that's what you're going to do, if you are going to be destroying
> >> your objects yourself, then what exactly are you going to gain by not
> >> freeing the memory, right then and there, instead of leaving it to the
> >> garbage collector to free the memory at some later, indeterminate point?

> > Mostly that this processing can be done at otherwise idle
> > moments, or spread over time instead of all at once (like
> > when deleting some dynamic data structure).

> And when your app does not have any idle moments, you end up
> running out of memory.

No, you end up running the garbage collector at a bad moment.

My own work doesn't involve applications which never have idle
moments, but I can easily imagine two cases:

-- large numeric applications, which only allocate a few large
arrays (everything else is on the stack)---in general, the
garbage collector will never run with these, but garbage
collection may not be appropriate, since it typically
requires more memory (and less time, but not in this case),
and

-- applications doing intensive calculations on graph
structures---garbage collection is a resounding win in terms
of development time for these, but using it will often
require a bit of tuning, explicitly triggering garbage
collection at moments when there are very few elements in
the graph. (Typically, manual allocation run time depends
on the number of allocations and frees, garbage collection
run time depends on the amount of memory allocated when the
collector runs.)

> <Splorf>

> That actually happened at day job, last week. A tick data app
> ran out of memory and crashed, because it kept chewing on the
> exchange's tick feed, and had no spare cycles for the Java VM
> to run the garbage collector, and release memory held my
> objects that were no longer in use.

Unless you've modified the JVM in some way, that simply cannot
happen. When Java runs out of memory, it automatically triggers
garbage collection. It sounds more like your application had a
memory leak. (Note that memory leaks are also possible without
garbage collection. In fact, garbage collection reduces the
risk of memory leaks. Without bringing it down to zero, of
course.)

James Kanze

unread,
Mar 2, 2008, 9:48:04 AM3/2/08
to
On 1 mar, 06:23, Ian Collins <ian-n...@hotmail.com> wrote:
> I V wrote:
> > On Fri, 29 Feb 2008 20:22:44 -0600, Sam wrote:

> But how does a user know if an object has to be deleted, or
> whether it can be left to the GC?

Maybe because he knows what the object is used for, and why he
created it in the first place?

> Languages like Java and JavaScript are unambiguous in this
> regard, everything gets mopped up by the GC. The languages
> design requires GC.

Java uses dynamic allocation even for value types. That pretty
much makes garbage collection a necessity, and not just an added
feature to improve programmer productivity.

C++, even with garbage collection, continues to support true
value types, and RAII continues to work as usual.

> It's the ambiguity with C++ I don't like, especially as C++
> provides language features that make GC an irrelevance.

Not an irrelevance. Less important, but programmer productivity
is never really irrelevant.

> For my own stuff, I pretty well use some form of smart pointer
> anywhere I would have used a raw pointer, so I have no need
> for any form of GC.

I tried that, and gave up with it. It resulted in too many
memory leaks. In my applications, most pointers are used for
navigation, not for ownership. And raw pointers work perfectly
well for navigation.

That doesn't mean that there aren't exceptions. I just finished
working on a large block of code which made extensive use of my
pre-boost shared pointer. But it was a closed system, with very
definite constraints on the dynamic memory (a parse tree, so no
cycles). Also, it represented very low level code, which must
be able to work even in systems where garbage collection isn't
an option---otherwise, garbage collection would have made coding
slightly easier (but only slightly, in this case---since the
shared pointer did work) and probably significantly faster
(but since the parse tree is mainly used in off line
calculations, speed really isn't an issue).

James Kanze

unread,
Mar 2, 2008, 9:54:55 AM3/2/08
to
On 1 mar, 03:11, Sam <s...@email-scan.com> wrote:
> James Kanze writes:
> > On Mar 1, 12:24 am, Sam <s...@email-scan.com> wrote:
> >> Richard Herring writes:
> >> > In message <cone.1204246382.29097.21741....@commodore.email-scan.com>,
> >> > Sam <s...@email-scan.com> writes

> >> Let me know when you figure out why, in Java, you have to
> >> throw all these try/catch blocks around, every time you
> >> need to deal with files or sockets,

> > Because Java doesn't have local objects or destructors. Which

> Java most certainly has destructors. See
> java.lang.Object.finalize().

Finalization is a completely separate concept from destruction.
The proposals for garbage collection in C++ also include
finalization, but in addition to, not in lieu of destructors.
The two concepts fulfil completely different roles.

> Java has local objects too. But that's going to be your
> homework assignment for today.

All objects in Java are allocated dynamically. Java has a few,
special types which are not objects, and which cannot be
allocated dynamically.

> > has nothing to do with garbage collection.

> It has everything to do with garbage collection.

Only for people who don't understand what garbage collection is
or does, or how C++ works.

> >> in order not to run out of available file descriptors.

> > In Java, you use try/catch blocks, and in C++, you use
> > destructors.

> Whoooooooosh!!! Right over your head.

It's becoming more and more apparent that you don't really know
either C++ or Java. In both languages, a file descripter is
freed when you close the file. Nothing to do with garbage
collection. Or destructors, really---you need to check the
return code of the close(), and do something if the close fails,
so you really can't defer it to the constructor anyway.

> > Garbage collection has nothing to do with the issue.

> You keep repeating this, but repeating something, over and
> over again, does not necessarily make it true.

Well, no one has yet shown the slightest relationship between
the two. In the absense of a relationship, it would seem that
you're the one repeating the same untruth over and over.

James Kanze

unread,
Mar 2, 2008, 10:01:26 AM3/2/08
to
On 1 mar, 04:55, Sam <s...@email-scan.com> wrote:
> Ian Collins writes:
> > Sam wrote:
> >> James Kanze writes:

> >>> On Mar 1, 12:24 am, Sam <s...@email-scan.com> wrote:
> >>>> Richard Herring writes:
> >>>> > In message <cone.1204246382.29097.21741....@commodore.email-scan.com>,
> >>>> > Sam <s...@email-scan.com> writes

> >>>> Let me know when you figure out why, in Java, you have to
> >>>> throw all these try/catch blocks around, every time you need
> >>>> to deal with files or sockets,

> >>> Because Java doesn't have local objects or destructors. Which

> >> Java most certainly has destructors. See
> >> java.lang.Object.finalize().

> > But that's not an automatic destructor in the C++ sense, is it?

It has nothing to do with a destructor in the C++ sense, and
serves a completely different role.

> It is a destructor in the C++ sense as in "gets invoked before
> the object's memory is released".

That's not what a destructor is in C++ (and not necessarily
true---typically, it's not true for local variables, nor for
static objects, nor for member variables, for example). A
destructor in C++ is a function which is called at a specific
time, and "deconstructs" an object into raw memory.

If the destructor is called as part of a delete expression, then
operator delete() will be called immediately afterwards, which
may or may not immediately free the memory. (Typically, it will
immediately free the memory, except in some cases where the
delete is called in a different thread than the corresponding
new.)

> That's precisely the point I am making.

The problem is that the point you're making is simply false.

> Garbage collection's only benefit is to clean up your objects
> when you can't keep track of their lifetime, and must rely on
> the garbage collector to destroy the objects when they no
> longer have any strong references.

That's the first time I've heard that. No one arguing in favor
of garbage collection has presented such an argument.

Rather than inventing idiocies, and then proving them false, you
should try addressing what people are really saying.

James Kanze

unread,
Mar 2, 2008, 10:06:52 AM3/2/08
to
On 1 mar, 06:14, Kai-Uwe Bux <jkherci...@gmx.net> wrote:

[...]


> Are you sure that garbage collectors for C++ _destroy_ objects
> that become unreachable? I was under the impression that they
> only reclaim the memory and do not invoke the destructor.

That's because you actually know what you're talking about, and
having just imagined some strawman to argue against.

Destructors have no relationship with Java's finalize method.
The closest concept to destructors in Java is a finally block.
There are a few special cases where a finally block works better
than destructors (closing files is an obvious example, where
only the user can know what the appropriate behavior is in case
of an error), but they are IMHO very much the exception---for
something between 90% and 99% of the time, destructors are
preferable.

In most cases (there are a few exceptions), finalization is
really only usable for error detection. (I've written large
applications in Java, and have never used it.)

Ioannis Vranos

unread,
Mar 2, 2008, 10:24:44 AM3/2/08
to
James Kanze wrote:
> Java uses dynamic allocation even for value types. That pretty
> much makes garbage collection a necessity, and not just an added
> feature to improve programmer productivity.
>
> C++, even with garbage collection, continues to support true
> value types, and RAII continues to work as usual.


Keep in mind that "Java" is two things. "Java" the language+ Java
Virtual Machine. They could provide the JVM with a common API for many
languages, as MS does with .NET.

In "VC++ .NET" case we have, ISO C++ language for native code, C++/CLI
language for interaction with the .NET VM + .NET VM. The plus of this is
that all these can be combined, native code with VM code.

I am not sure how pretty C++/CLI is though (I learned .NET programming
with "C++ managed extensions", the "ancestor" of C++/CLI), however while
C++/CLI was under development it was breaking common C++ semantics (like
default inheritance for "managed classes" being public instead of
private), while "C++ managed extensions" that I learned didn't break these.

Sam

unread,
Mar 2, 2008, 10:55:04 AM3/2/08
to
James Kanze writes:

> On 1 mar, 03:22, Sam <s...@email-scan.com> wrote:
>
>> If you separate the object destruction phase from the memory
>> release phase,
>
> You don't change much.

My point exactly. You're arguing for the sake of arguing.

>> then you must be asserting that you are going to be explicitly
>> invoking the object destruction phase, at some point,
>> yourself, instead of relying on the garbage collector on doing
>> that.
>
> Certainly. The garbage collector never invokes object
> destruction. The two things are separate concepts, and as such
> should be disassociated.

Irrelevant. Whether or not they are separate concepts reflects nothing on
the fact that separating their respective occurences buys you nothing, or
makes any sense.

>
>> > If you have to do something special when
>> > an object's lifetime ends, then you have to do it.
>
>> Bravo! You finally got it.
>
> What do you mean, finally. This has always been a fundamental
> concept for any competent programmer.

Not the ones that rely on garbage collection. After all, if they did
undertand the concept, they would understand when their objects' lifetime
has expired, and they can be destroyed and their memory gets reclaimed.

> What you seem to be missing is the "if". In a lot of
> applications, that if will usually be false, so the then part of
> the sentence doesn't apply. Obviously, you need to do the
> analysis to determine if it applies, but you need to do that
> anyway, garbage collection or not---you need to know what to put
> in the destructor before you write it. The difference when
> using garbage collection is that if that analysis shows that
> nothing really needs to be done (except memory management),
> you're through. You've finished the job. Without garbage
> collection, you've still got code to write.

You seem to be carrying a misunderstanding that just because an explicit
class destructor is not required, it must mean that the class destructor
does not exist.

That, of course, is wrong. The class may, for example, contain member
objects that themselves have an explicit destructor. Therefore, even if you
do not need to code an explicit destructor, it still, heavens-to-Betsy,
exists. For the obvious reasons.

So you really can't just wash your hands of the whole matter, by the virtue
of claiming that you do not need to write a destructor for your class.
That's because there's always a destructor, for every class. Just because
you do not have to explicitly define one, does not mean that the class
destructor does not exist. This does not excuse you from the resposibility
of properly implementing your object's lifetime, and instead foisting it off
on some sloppy garbage collector.

Generic garbage collection in the C++ context never takes form of "well, you
explicitly invoke the destructor when you should, and I'll take care of
releasing the memory at some point later down the line". It's always "well,
don't worry about the objects, when I figure out they're no longer needed,
I'll destroy them and reclaim their memory".

>> If you're going to explicitly destroy the object, then you're
>> going to free the memory right than and there.
>
> Maybe. You might want to keep it as long as there are pointers
> to it, for error checking.

Brilliant. And when you figure out that no such pointers exists, you're
going to finally kiss it good-bye, right? It's amazing how better this
approach is, rather than just using shared_ptr (or a better implemented
alternative). Why have to use such a bland concept like shared_ptr, when you
can use this wonderfully-convoluted object model?

>> To stop short before doing that, and leaving it to the garbage
>> collector, is absolutely demented, and you gain absolutely
>> nothing from doing that.
>
> You gain robustness, when you need to explicitly dispose of the
> object, and a lot less code to write, when you don't.

You certainly need a lot less code to write if you disclaim the
responsibility of properly tracking the objects' lifetime, and foisting it
off on some garbage collection algorithm.

I would not call that "robust", by any stretch of imagination.

>> > Garbage collection or not.
>
>> If you're going to use a garbage collection model,
>
> Garbage collection isn't a model. It's a tool. Maybe that's
> where you're having problems with it.

Here's another hair to split, for you: _____________________

Of course it's a tool. It's a tool for those who are too lazy, or
incompetent, to properly design their classes, and track their instances'
lifetime.

>> Refusing to do that, and instead choosing to foist a
>> completely unnecessary garbage collection framework on your
>> neck, in that situation, is completely and utterly retarded.
>
>> And that's precisely why I wrote, right from the start, that
>> garbage collection is only for those who are too stupid to
>> manage and keep track of their objects, and their lifetime,
>> themselves.
>
> Which, of course, is false. No professional, today, would start
> a new C++ application without considering garbage collection,
> any more than he'd start it without considering templates, or
> threads, or any other feature readily available.

Your definition of "professional" does not seem to be the same one as
mine's. If I see someone's spaghetti code missing the obvious deletes, in
the appropriate places, I ask them about it, and they say "oh, don't worry
about, the garbage collector will take care of it", I would not describe
such a person as a "professional".

Sam

unread,
Mar 2, 2008, 10:55:16 AM3/2/08
to
James Kanze writes:

Don't take my word for it.

http://java.sun.com/docs/white/langenv/Simple.doc1.html

# The Java run-time system takes advantage of these idle periods and runs
# the garbage collector in a low priority thread when no other threads are
# competing for CPU cycles.


Sam

unread,
Mar 2, 2008, 10:56:20 AM3/2/08
to
James Kanze writes:

> On 1 mar, 03:11, Sam <s...@email-scan.com> wrote:

>
>> >> in order not to run out of available file descriptors.
>
>> > In Java, you use try/catch blocks, and in C++, you use
>> > destructors.
>
>> Whoooooooosh!!! Right over your head.
>
> It's becoming more and more apparent that you don't really know
> either C++ or Java. In both languages, a file descripter is
> freed when you close the file. Nothing to do with garbage
> collection.

It's already apparent that you don't really understand the problems with
garbage collection, as it gets clearly demonstrated the Java model, and why
it forces you to explicitly code exception handling, when dealing with
external resources, thus defeating the very thing that's touted as Java's
advantage of not forcing the programmer to manage the object's lifetimes,
and letting the VM take care of it.

I'll spell it out, but just once. You're constructing a java object that
contains a java.io.File, as one of its members (or any other object that
refers to some external resource). Right after you acquire the external
resource (by opening the file, or an equivalent operation on another type of
a resource), you must immediately have a try/catch block that will release
the external resource if an exception occurs before the object gets
completely constructed. Because if one occurs and you don't catch it, then,
due to the wonders of the Java VM, that java.io.File object will still exist
and claim the external resource, until the VM decides to GC it. So, lather,
rinse, repeat, and you're out of file descriptors, since the VM thinks it
still has plenty of memory, and it doesn't bother to finalize and collect
all the java.io.File objects that are littering the heap.

And you now have to percolate and code the same clumsy exception handling
all the way up your class hierarchy, and with anything else that touches any
part of this class hierarchy. Your homework assignment is to figure out why.

There you go, the wonderful advantages of garbage collection, for you.

> Or destructors, really---you need to check the
> return code of the close(), and do something if the close fails,
> so you really can't defer it to the constructor anyway.

WHOOOOOOOOOOOOSH!!! Right over your head, again.


Ian Collins

unread,
Mar 2, 2008, 1:17:30 PM3/2/08
to
James Kanze wrote:
> On 1 mar, 06:23, Ian Collins <ian-n...@hotmail.com> wrote:
>> I V wrote:
>>> On Fri, 29 Feb 2008 20:22:44 -0600, Sam wrote:
>
>> But how does a user know if an object has to be deleted, or
>> whether it can be left to the GC?
>
> Maybe because he knows what the object is used for, and why he
> created it in the first place?

But he'd have to whether the object had to be deleted, or could be left
for the GC.

>> It's the ambiguity with C++ I don't like, especially as C++
>> provides language features that make GC an irrelevance.
>
> Not an irrelevance. Less important, but programmer productivity
> is never really irrelevant.
>

I still contend that correct and systematic use of smart pointers does
make GC an irrelevance without any sacrifice in productivity.

>> For my own stuff, I pretty well use some form of smart pointer
>> anywhere I would have used a raw pointer, so I have no need
>> for any form of GC.
>
> I tried that, and gave up with it. It resulted in too many
> memory leaks. In my applications, most pointers are used for
> navigation, not for ownership. And raw pointers work perfectly
> well for navigation.
>

Ah, well that's where our domains differ. Most of the places where I
would have used pointers are in containers, manipulating DOM trees or
for passing objects between threads. Moving to smart pointers made life
so much easier.

--
Ian Collins.

Ian Collins

unread,
Mar 2, 2008, 1:19:29 PM3/2/08
to
James Kanze wrote:
> On 1 mar, 04:55, Sam <s...@email-scan.com> wrote:
>> Ian Collins writes:
>>> Sam wrote:
>>>> James Kanze writes:
>
>>>>> On Mar 1, 12:24 am, Sam <s...@email-scan.com> wrote:
>>>>>> Richard Herring writes:
>>>>>>> In message <cone.1204246382.29097.21741....@commodore.email-scan.com>,
>>>>>>> Sam <s...@email-scan.com> writes
>
>>>>>> Let me know when you figure out why, in Java, you have to
>>>>>> throw all these try/catch blocks around, every time you need
>>>>>> to deal with files or sockets,
>
>>>>> Because Java doesn't have local objects or destructors. Which
>
>>>> Java most certainly has destructors. See
>>>> java.lang.Object.finalize().
>
>>> But that's not an automatic destructor in the C++ sense, is it?
>
> It has nothing to do with a destructor in the C++ sense, and
> serves a completely different role.
>
Isn't that what I said?

--
Ian Collins.

Juha Nieminen

unread,
Mar 2, 2008, 2:56:34 PM3/2/08
to
James Kanze wrote:
> Yes. In a lot of applications, garbage collection is faster,
> but typically, it uses more memory. Given the size of current
> memories, this usually isn't an issue (but it could be in some
> applications, particularly numeric simulations of large scale
> physical phenomena, like weather).

There are other less-understood problems with garbage collection which
few people realize.

One such problem is that garbage collection can be quite detrimental
with respect to swapping.

Typically if a program allocates fair amounts of memory, but is
otherwise designed to simply sit idly on the background most of the time
and run from time to time to make some light tasks (such as many device
managers and such in Windows do), the majority of their unused allocated
memory will be swapped to disk, especially if other applications request
that memory. If the tasks this program is asked to perform never read
the swapped blocks, they will stay in the swap.

However, if the program in question uses GC, and the GC engine happens
to be triggered at some point, it will scan all the memory blocks the
program is using. Naturally if these memory blocks were in the swap,
they will be swapped to memory from there. If there was nothing to
garbage-collect, this swapping-out was a completely useless waste of
resources.

This can become extremely detrimental if the system was running very
low on memory to begin with. If an inappropriate GC engine happens to be
triggered at the wrong time, it can cause unnecessary swapping where
none would have been needed, disrupting the major task the system was
performing at that moment.

"Those device apps don't use GC." Oh, but they do. They do. GC is the
current trend, and they follow it.

jason.c...@gmail.com

unread,
Mar 2, 2008, 3:17:46 PM3/2/08
to
On Mar 2, 2:56 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> [snip]

> There are other less-understood problems with garbage collection which
> few people realize.
>
> One such problem is that garbage collection can be quite detrimental
> with respect to swapping.
> [snip]

I can speak for this; this was especially a problem on Apple's JVM, at
least as of about a year ago, I'm not sure if they've fixed the issues
since. In particular, there was a rather memory-intensive, popular
online game that stored most of it's graphics in system memory, and
when it decided to run the GC it would have to swap in all the pages
-- and it crippled the *entire* system for 30-45 seconds every 10
minutes or so. It was very unacceptable, and made the game virtually
unplayable for nearly all of the Mac users who were trying to play it.

It was a problem that did not happen on non-Apple JVM's. I think the
major problem there was Apple's algorithm for deciding when to run the
garbage collector -- it seemed to only run it when the system was
running low on memory, waiting until the last minute. Unfortunately,
this also meant most of the "garbage" was probably in the page file.
If it had run the garbage collector more frequently, perhaps at
regular intervals, I do not think that issue would have occurred.

Still, in that case, it seemed like more of a specific GC
implementation issue rather than a problem with garbage collection
itself. The problem was unique to Apple's JVM.

Just thought I'd share the memory of that game,
Jason

peter koch

unread,
Mar 2, 2008, 3:19:24 PM3/2/08
to
On 2 Mar., 19:17, Ian Collins <ian-n...@hotmail.com> wrote:
> James Kanze wrote:
> > On 1 mar, 06:23, Ian Collins <ian-n...@hotmail.com> wrote:
> >> I V wrote:
> >>> On Fri, 29 Feb 2008 20:22:44 -0600, Sam wrote:
>
> >> But how does a user know if an object has to be deleted, or
> >> whether it can be left to the GC?
>
> > Maybe because he knows what the object is used for, and why he
> > created it in the first place?
>
> But he'd have to whether the object had to be deleted, or could be left
> for the GC.
>

That is a theoretical problem, yes. For an encapsulated object you
might not know if it has any real resources. Worse is that you might
have a base object and have no idea as to what happens in the
subobject.
In practice it might not be a real problem. I could easily imagine
problematic cases, but this is not a big problem and could be solved
by e.g. documenting the base class as e.g. "you are not allowed to
obtain any resources here".
The biggest problem is with template programming. My guess is that
programming on this abstraction-level will often require an extra
level of support or some exttra careful programming.

[snip]


>
> Ah, well that's where our domains differ.  Most of the places where I
> would have used pointers are in containers, manipulating DOM trees or
> for passing objects between threads.  Moving to smart pointers made life
> so much easier.

I have the same experience as you: it would never have been a major
convenience for me to have a garbage collector, but I've had great use
for smart pointers.

/Peter

James Kanze

unread,
Mar 2, 2008, 6:43:36 PM3/2/08
to

> http://java.sun.com/docs/white/langenv/Simple.doc1.html

In addition to running it when there is no memory available for
a new. That's a simple (and frequently applied) optimization
measure, but it doesn't change the fact that if your application
doesn't leak memory, and doesn't require more than the available
memory, it will not crash because of a lack of memory. In other
words, the scenario that you described isn't possible.

James Kanze

unread,
Mar 2, 2008, 6:51:07 PM3/2/08
to
On 2 mar, 19:17, Ian Collins <ian-n...@hotmail.com> wrote:
> James Kanze wrote:
> > On 1 mar, 06:23, Ian Collins <ian-n...@hotmail.com> wrote:
> >> I V wrote:
> >>> On Fri, 29 Feb 2008 20:22:44 -0600, Sam wrote:

> >> But how does a user know if an object has to be deleted, or
> >> whether it can be left to the GC?

> > Maybe because he knows what the object is used for, and why he
> > created it in the first place?

> But he'd have to whether the object had to be deleted, or
> could be left for the GC.

Certainly. But that's always the case. You don't create
objects without knowing the role of the object, or what it's
there for.

> >> It's the ambiguity with C++ I don't like, especially as C++
> >> provides language features that make GC an irrelevance.

> > Not an irrelevance. Less important, but programmer productivity
> > is never really irrelevant.

> I still contend that correct and systematic use of smart pointers does
> make GC an irrelevance without any sacrifice in productivity.

It adds to the programmer work load. It's more code you have to
write.

> >> For my own stuff, I pretty well use some form of smart pointer
> >> anywhere I would have used a raw pointer, so I have no need
> >> for any form of GC.

> > I tried that, and gave up with it. It resulted in too many
> > memory leaks. In my applications, most pointers are used for
> > navigation, not for ownership. And raw pointers work perfectly
> > well for navigation.

> Ah, well that's where our domains differ. Most of the places where I
> would have used pointers are in containers, manipulating DOM trees or
> for passing objects between threads.

I don't know what a DOM tree is, but I certainly keep pointers
in containers, and I do pass them between threads. Passing them
between threads is one case where I do use a smart
pointer---std::auto_ptr---because once I've handed the object
off, I don't want to be able to access it again in the
originating thread. (The objects passed between threads are
almost always "agents".)

Most of my entity objects are related to other objects, and
contain pointers to these other objects. Raw pointers, since no
ownership is involved. And most of my containers are also used
for navigation---either a 1 to n relationship, or for lookup
(finding the object from an external name). Again, raw pointers
fill the bill perfectly.

> Moving to smart pointers made life so much easier.

If you don't have garbage collection, smart pointers may be
better than nothing. In some cases. I use all three: raw
pointers (for pure navigation), garbage collection (for memory
management) and smart pointers (for special cases like passing
between threads, or associating a lock with a pointer). If for
some reason I can't use garbage collection, then I'll also use
smart pointers to simulate it. But that requires some
additional effort.

James Kanze

unread,
Mar 2, 2008, 7:13:39 PM3/2/08
to
On 2 mar, 16:55, Sam <s...@email-scan.com> wrote:
> James Kanze writes:
> > On 1 mar, 03:22, Sam <s...@email-scan.com> wrote:

> >> If you separate the object destruction phase from the memory
> >> release phase,

> > You don't change much.

> My point exactly. You're arguing for the sake of arguing.

No. You said that they were more or less one and the same
thing. They aren't, at least not in C++. They are basically
two distinct operations, which are in once special case invoked
by the same expression.

> >> then you must be asserting that you are going to be explicitly
> >> invoking the object destruction phase, at some point,
> >> yourself, instead of relying on the garbage collector on doing
> >> that.

> > Certainly. The garbage collector never invokes object
> > destruction. The two things are separate concepts, and as such
> > should be disassociated.

> Irrelevant. Whether or not they are separate concepts reflects
> nothing on the fact that separating their respective
> occurences buys you nothing, or makes any sense.

Which doubtlessly explains why in C++ they are completely
separated into two separate functions, why in the STL (and every
other library of containers I've used) they are separate.

The fact remains that they are two separate concepts, and
combining to concerns in one action is never a good thing. It's
a violation of basic good design principles.

> >> > If you have to do something special when
> >> > an object's lifetime ends, then you have to do it.

> >> Bravo! You finally got it.

> > What do you mean, finally. This has always been a fundamental
> > concept for any competent programmer.

> Not the ones that rely on garbage collection.

Where do you get that idea? In the Java projects I've worked
on, we've always considered object lifetime issues.

> After all, if they did undertand the concept, they would
> understand when their objects' lifetime has expired, and they
> can be destroyed and their memory gets reclaimed.

Certainly. Anyone who can write correct code with garbage
collection can write it without, just as anyone who cannot write
correct code without garbage collection can't write it with.
That's never been in doubt. The difference is simply that if
you do know how to write correct code, it requires less work to
do so with garbage collection.

> > What you seem to be missing is the "if". In a lot of
> > applications, that if will usually be false, so the then part of
> > the sentence doesn't apply. Obviously, you need to do the
> > analysis to determine if it applies, but you need to do that
> > anyway, garbage collection or not---you need to know what to put
> > in the destructor before you write it. The difference when
> > using garbage collection is that if that analysis shows that
> > nothing really needs to be done (except memory management),
> > you're through. You've finished the job. Without garbage
> > collection, you've still got code to write.

> You seem to be carrying a misunderstanding that just because
> an explicit class destructor is not required, it must mean
> that the class destructor does not exist.

> That, of course, is wrong. The class may, for example, contain
> member objects that themselves have an explicit destructor.
> Therefore, even if you do not need to code an explicit
> destructor, it still, heavens-to-Betsy, exists. For the
> obvious reasons.

You seem to be carrying a misunderstanding that people write
code at random, without doing any proper design first. And that
people will take an interface designed to fulfil one role in the
application, and use it to do something completely different.
Such techniques don't work. Garbage collection or not.

> So you really can't just wash your hands of the whole matter,
> by the virtue of claiming that you do not need to write a
> destructor for your class. That's because there's always a
> destructor, for every class. Just because you do not have to
> explicitly define one, does not mean that the class destructor
> does not exist. This does not excuse you from the
> resposibility of properly implementing your object's lifetime,
> and instead foisting it off on some sloppy garbage collector.

You don't seem to understand that good code is designed. It
doesn't just happen. (And again, garbage collection changes
nothing at that level.)

> Generic garbage collection in the C++ context never takes form
> of "well, you explicitly invoke the destructor when you
> should, and I'll take care of releasing the memory at some
> point later down the line".

Exactly. You invoke the destructor IF the object has
significant behavior which must be done at the end of its
lifetime. Otherwise, you don't bother. There are whole classes
of object types which by definition won't have significant
behavior which must be done at the end of their lifetime. There
are even object types which don't really have a defined
lifetime. And whether you invoke the destructor or not,
sometime later, WHEN no one else can access the object, the
memory it occupies will be reclaimed.

And that's a very big WHEN, because just because you've
destructed the object doesn't mean that no one else will access
it. With garbage collection, of course, you can verify that no
one does, and cause an assertion failure if they try to.
Without garbage collection, the memory may have been recycled,
and it's anyone's guess.

> It's always "well, don't worry about the objects, when I
> figure out they're no longer needed, I'll destroy them and
> reclaim their memory".

Why do you keep repeating this, when it's been explained that it
is false. Garbage collection doesn't destruct anything, it just
reclaims memory which is otherwise inaccessible.

> >> If you're going to explicitly destroy the object, then you're
> >> going to free the memory right than and there.

> > Maybe. You might want to keep it as long as there are pointers
> > to it, for error checking.

> Brilliant. And when you figure out that no such pointers
> exists, you're going to finally kiss it good-bye, right?

When no such pointers exist, no one can incorrecly access the no
longer existing object. So it no longer matters if the memory
image is there or not.

> It's amazing how better this approach is, rather than just
> using shared_ptr (or a better implemented alternative). Why
> have to use such a bland concept like shared_ptr, when you can
> use this wonderfully-convoluted object model?

Because shared_ptr doesn't work, and garbage collection does?

> >> To stop short before doing that, and leaving it to the garbage
> >> collector, is absolutely demented, and you gain absolutely
> >> nothing from doing that.

> > You gain robustness, when you need to explicitly dispose of the
> > object, and a lot less code to write, when you don't.

> You certainly need a lot less code to write if you disclaim
> the responsibility of properly tracking the objects' lifetime,
> and foisting it off on some garbage collection algorithm.

It would help discussion if you'd at least try to be a little
bit honest. It's now been explained I don't know how many times
that garbage collection has nothing to do with object lifetime.
Except that it does allow detection of the error of accidentally
trying to access an object which no longer exists.

> I would not call that "robust", by any stretch of imagination.

You call random (undefined) behavior more robust than detecting
programming errors?

> >> > Garbage collection or not.

> >> If you're going to use a garbage collection model,

> > Garbage collection isn't a model. It's a tool. Maybe that's
> > where you're having problems with it.

> Here's another hair to split, for you: _____________________

I'm not splitting hairs. The problem is that you just don't
seem to understand the basic C++ object mode, and the role
garbage collection plays in it.

> Of course it's a tool. It's a tool for those who are too lazy,
> or incompetent, to properly design their classes, and track
> their instances' lifetime.

It's a tool for those who are too professional to artificially
create unnecessary work, just so that they can bill extra hours.
It's a tool for those who insist on robust software, with
serious error detection.

> >> Refusing to do that, and instead choosing to foist a
> >> completely unnecessary garbage collection framework on your
> >> neck, in that situation, is completely and utterly retarded.

> >> And that's precisely why I wrote, right from the start, that
> >> garbage collection is only for those who are too stupid to
> >> manage and keep track of their objects, and their lifetime,
> >> themselves.

> > Which, of course, is false. No professional, today, would start
> > a new C++ application without considering garbage collection,
> > any more than he'd start it without considering templates, or
> > threads, or any other feature readily available.

> Your definition of "professional" does not seem to be the same
> one as mine's.

I haven't figured yours out yet. Mine is simple: I develop
reliable and maintainable software, at the lowest possible cost
to my customer. Not using tools that effectively reduce my
workload and increase the reliability of the software would be
unprofessional, or even dishonest.

> If I see someone's spaghetti code missing the obvious deletes,
> in the appropriate places, I ask them about it, and they say
> "oh, don't worry about, the garbage collector will take care
> of it", I would not describe such a person as a
> "professional".

In other words, the more deletes, the more professional.
Strange definition, to say the least.

James Kanze

unread,
Mar 2, 2008, 7:15:08 PM3/2/08
to

Yes. I wasn't disagreeing with you. Just trying to say it in
an even stronger way.

Ian Collins

unread,
Mar 2, 2008, 7:20:55 PM3/2/08
to
James Kanze wrote:
> On 2 mar, 19:17, Ian Collins <ian-n...@hotmail.com> wrote:
>> James Kanze wrote:
>>> On 1 mar, 06:23, Ian Collins <ian-n...@hotmail.com> wrote:

>>>> But how does a user know if an object has to be deleted, or
>>>> whether it can be left to the GC?
>
>>> Maybe because he knows what the object is used for, and why he
>>> created it in the first place?
>
>> But he'd have to whether the object had to be deleted, or
>> could be left for the GC.
>
> Certainly. But that's always the case. You don't create
> objects without knowing the role of the object, or what it's
> there for.
>

But why add yet another facet?

>>>> It's the ambiguity with C++ I don't like, especially as C++
>>>> provides language features that make GC an irrelevance.
>
>>> Not an irrelevance. Less important, but programmer productivity
>>> is never really irrelevant.
>
>> I still contend that correct and systematic use of smart pointers does
>> make GC an irrelevance without any sacrifice in productivity.
>
> It adds to the programmer work load. It's more code you have to
> write.
>

No, once written, smart pointer types can be used just like any other,
no extra work at all. One may have to choose which type to use and
there is always the risk of getting it wrong. But the same could happen
with a mix of GC and user managed objects.

As I said before, it's not GC I object to, it's mixing GC and
"conventional" memory management. I'd also object the mixing raw
pointers with smart pointers for dynamic objects.

>>> I tried that, and gave up with it. It resulted in too many
>>> memory leaks. In my applications, most pointers are used for
>>> navigation, not for ownership. And raw pointers work perfectly
>>> well for navigation.
>
>> Ah, well that's where our domains differ. Most of the places where I
>> would have used pointers are in containers, manipulating DOM trees or
>> for passing objects between threads.
>
> I don't know what a DOM tree is

The Document Object Model. I do a lot of work with XML and XHTML documents!

--
Ian Collins.

James Kanze

unread,
Mar 2, 2008, 7:24:52 PM3/2/08
to
On 2 mar, 16:56, Sam <s...@email-scan.com> wrote:
> James Kanze writes:
> > On 1 mar, 03:11, Sam <s...@email-scan.com> wrote:

> >> >> in order not to run out of available file descriptors.

> >> > In Java, you use try/catch blocks, and in C++, you use
> >> > destructors.

> >> Whoooooooosh!!! Right over your head.

> > It's becoming more and more apparent that you don't really know
> > either C++ or Java. In both languages, a file descripter is
> > freed when you close the file. Nothing to do with garbage
> > collection.

> It's already apparent that you don't really understand the
> problems with garbage collection,

Until now, it's been you whose shown an absense of
understanding---of garbage collection, of program design, of the
C++ object model. I'm beginning to wonder what you do
understand.

> as it gets clearly demonstrated the Java model,

Java is not C++, and it uses different paradigms. Garbage
collection is essential in Java, because all objects must be
allocated dynamically, and user defined types can't have value
semantics. It's optional in C++, because we do have value
semantics. Optional, but it still saves the programmer some
unnecessary work.

> and why it forces you to explicitly code exception handling,
> when dealing with external resources,

The reason you need explict try/catch or try/finally blocks in
Java is because that's Java's model. In C++, you use
destructors.

Garbage collection has absolutely nothing to do with it. The
absense of on stack objects and destructors is the key
difference here.

> thus defeating the very thing that's touted as Java's
> advantage of not forcing the programmer to manage the object's
> lifetimes, and letting the VM take care of it.

Some advertising writers may claim that, but no professional
programmer, regardless of the language he uses, would pretend
that you can ignore object lifetimes. The authors of the Java
standard library certainly didn't.

> I'll spell it out, but just once. You're constructing a java
> object that contains a java.io.File, as one of its members (or
> any other object that refers to some external resource). Right
> after you acquire the external resource (by opening the file,
> or an equivalent operation on another type of a resource), you
> must immediately have a try/catch block that will release the
> external resource if an exception occurs before the object
> gets completely constructed. Because if one occurs and you
> don't catch it, then, due to the wonders of the Java VM, that
> java.io.File object will still exist and claim the external
> resource, until the VM decides to GC it. So, lather, rinse,
> repeat, and you're out of file descriptors, since the VM
> thinks it still has plenty of memory, and it doesn't bother to
> finalize and collect all the java.io.File objects that are
> littering the heap.

And why? That's not because of garbage collection---the
situation would be exactly the same if you created an ofstream
dynamically, instead of making it a member. The reason is
because Java doesn't have destructors, nor true member
subobjects.

(Of course, files are a special case, because you wouldn't
normally close them in a destructor anyway.)

> And you now have to percolate and code the same clumsy
> exception handling all the way up your class hierarchy, and
> with anything else that touches any part of this class
> hierarchy. Your homework assignment is to figure out why.

> There you go, the wonderful advantages of garbage collection,
> for you.

The problem with all of your arguments is that they have
absolutely nothing to do with garbage collection.

> > Or destructors, really---you need to check the
> > return code of the close(), and do something if the close fails,
> > so you really can't defer it to the constructor anyway.

> WHOOOOOOOOOOOOSH!!! Right over your head, again.

Why is it that whenever I bring up an irrefutable point (e.g.
the necessity of checking the status after close), you go off
the edge?

Ioannis Vranos

unread,
Mar 2, 2008, 7:37:40 PM3/2/08
to
James Kanze wrote:
>
>>> It has nothing to do with a destructor in the C++ sense, and
>>> serves a completely different role.
>
>> Isn't that what I said?
>
> Yes. I wasn't disagreeing with you. Just trying to say it in
> an even stronger way.


Leaving "Java" apart, which is a close language syntax + virtual machine
combination, you may check this regarding C++/CLI:

http://en.wikipedia.org/wiki/C%2B%2B/CLI


The managed class ("ref class") comes with both a deterministic
destructor and a non-deterministic destructor (called by the GC). If you
the managed object reaches the end of its scope (the managed objects can
be like regular objects and not required to be allocated by gcnew), or
you delete them explicitly if you have created them with gcnew, the
deterministic destructor is called. If you have allocated the managed
object with gcnew and you leave it to be garbage collected, the
non-deterministic destructor is called. I think this is a very good
approach. At the same time, ISO C++ code can be used stand-alone or
mixed with managed code.


Even at the time I was creating .NET applications with "C++ managed
extensions" where every managed object had to be allocated with __gcnew
and left to be destroyed by the GC, while you could define an explicit
function to call so as to free allocated resources explicitly when you
wanted, and not wait for GC to free the resources by calling the
Finalizer (the non-deterministic destructor that was the only kind of
destructor for managed classes), leaving all those Forms, Buttons etc to
the GC was a great relief, not having to worry about explicitly
releasing all those stuff. So I think in normal PC GUI
applications,garbage collection has a place to make the programmer's
life easier, where space efficiency is not a primary concern (that is
for the usual user applications).


I remember some company or MS had ported Quake II to .NET and the
runt-time cost was only about 10%. So even Quake II where speed is a
primary concern, the GC didn't cause much trouble, but rather it helped
much.


GC has a place in the present and in the future, I think all must come
in terms with that. We can't stick in the past, technology is moving
forward. If you like it, use it, if you don't like it, don't use it.

Ioannis Vranos

unread,
Mar 2, 2008, 7:47:27 PM3/2/08
to

Sam

unread,
Mar 2, 2008, 11:19:30 PM3/2/08
to
James Kanze writes:

> On 2 mar, 16:55, Sam <s...@email-scan.com> wrote:
>> James Kanze writes:
>> > On 1 mar, 03:22, Sam <s...@email-scan.com> wrote:
>
>> >> If you separate the object destruction phase from the memory
>> >> release phase,
>
>> > You don't change much.
>
>> My point exactly. You're arguing for the sake of arguing.
>
> No. You said that they were more or less one and the same
> thing. They aren't, at least not in C++.

Here's another hair for you to split: ______________________________

> They are basically
> two distinct operations, which are in once special case invoked
> by the same expression.

Anyone who is not involved with splitting hairs, for a living, would clearly
understand that I was referring to the fact that "delete" does both:
destruction and memory reclamation. It's one shot, in C++.

>> Irrelevant. Whether or not they are separate concepts reflects
>> nothing on the fact that separating their respective
>> occurences buys you nothing, or makes any sense.
>
> Which doubtlessly explains why in C++ they are completely
> separated into two separate functions,

Damn right! There's no such thing as "delete", in C++, which handles both
object destruction and memory release. There's a "foo", that does the first
part, and "bar", that does the second one. My mistake.

>> It's always "well, don't worry about the objects, when I
>> figure out they're no longer needed, I'll destroy them and
>> reclaim their memory".
>
> Why do you keep repeating this, when it's been explained that it
> is false. Garbage collection doesn't destruct anything, it just
> reclaims memory which is otherwise inaccessible.

Why do you keep repeating this, that object destruction and memory release
are two completely separate processes in C++, when it's been explained to
you that it's completely false. Maybe on your planet C++ works this way, but
not on this one.

>> >> If you're going to explicitly destroy the object, then you're
>> >> going to free the memory right than and there.
>
>> > Maybe. You might want to keep it as long as there are pointers
>> > to it, for error checking.
>
>> Brilliant. And when you figure out that no such pointers
>> exists, you're going to finally kiss it good-bye, right?
>
> When no such pointers exist, no one can incorrecly access the no
> longer existing object. So it no longer matters if the memory
> image is there or not.

And how do you expect to arrive to such a conclusion? A random number
generator? Yippee! It evaluated to 0.53 -- must mean that no further
pointers remain, and we can reclaim the object.

>> It's amazing how better this approach is, rather than just
>> using shared_ptr (or a better implemented alternative). Why
>> have to use such a bland concept like shared_ptr, when you can
>> use this wonderfully-convoluted object model?
>
> Because shared_ptr doesn't work, and garbage collection does?

Not on my planet, where it works every time it's used properly, and garbage
collection is an ugly hack for the lazy asses who can't be bothered to track
and manage their objects, properly.

>> > You gain robustness, when you need to explicitly dispose of the
>> > object, and a lot less code to write, when you don't.
>
>> You certainly need a lot less code to write if you disclaim
>> the responsibility of properly tracking the objects' lifetime,
>> and foisting it off on some garbage collection algorithm.
>
> It would help discussion if you'd at least try to be a little
> bit honest. It's now been explained I don't know how many times
> that garbage collection has nothing to do with object lifetime.

Repeating the same absurdity a given number of times won't suddenly turn it
into sense. The whole and the only purpose of garbage collection is to clean
up after yourself, when you can't be bothered to do it properly. That's the
sole and the only purpose for it, because if you do know what you're doing,
you simply don't need garbage collection. Not in C++, at least.

> Except that it does allow detection of the error of accidentally
> trying to access an object which no longer exists.

Brilliant! "I'm too stupid to know how to track my objects' lifetime, so
I'll just use garbage collection in some twisted way, in order to save my
lazy ass."


>> I would not call that "robust", by any stretch of imagination.
>
> You call random (undefined) behavior more robust than detecting
> programming errors?

I call "knowing how to do your job, WRT class design an implementation" more
robust than using an ugly, revolting hack like C++-based garbage collection.

>> Here's another hair to split, for you: _____________________
>
> I'm not splitting hairs. The problem is that you just don't
> seem to understand the basic C++ object mode, and the role
> garbage collection plays in it.

There's no such thing as garbage collection in "basic C++ object mode." The
formal language just does not define anything of that sort. Feel free to
cite the part of ISO/IEC 14882:2003 that defines garbage collection for
"basic C++ object mode". Whatever that is.

Garbage collection for C++ always involves some third-party slapdash code
that seems to compete with Boost for the gold prize in the C++ obfuscation
context.

Actually, reflecting on the last 10+ years of looking at C++ code in
financial apps -- that are responsible for moving huge volumes of business
critical market data -- I do not recall even a single instance of anyone
using anything can even be remotely described, in some nightmarish context,
as "garbage collection." Sorry, but established facts disagree with your
theories.

>> Of course it's a tool. It's a tool for those who are too lazy,
>> or incompetent, to properly design their classes, and track
>> their instances' lifetime.
>
> It's a tool for those who are too professional to artificially
> create unnecessary work, just so that they can bill extra hours.

"C++ garbage collection" is the very essence of "unnecessary work".

> It's a tool for those who insist on robust software, with
> serious error detection.

You better sit down, because the following may come as a shock to you.

Sitting down? Ok.

Here's a newsflash: there's plenty of "robust software" going around that
does not involve garbage collection. Well, how'd that happen, huh?

>> > Which, of course, is false. No professional, today, would start
>> > a new C++ application without considering garbage collection,
>> > any more than he'd start it without considering templates, or
>> > threads, or any other feature readily available.
>
>> Your definition of "professional" does not seem to be the same
>> one as mine's.
>
> I haven't figured yours out yet. Mine is simple: I develop
> reliable and maintainable software, at the lowest possible cost
> to my customer. Not using tools that effectively reduce my
> workload and increase the reliability of the software would be
> unprofessional, or even dishonest.

That's your opinion. If I ever meet some candidate who walks off the street,
and starts spouting something or other about the wonders of garbage
collection in C++, I'll politely thank him, strike his name off the list,
and move on to the next one. Nobody who knows what he's doing, in C++, has
any use for this garbage collection nonsense.

See -- I prefer to use "tools" and "approaches" that eliminate even the
possibility of memory corruption, using some basic and simple programming
practices. Or at least most of it, instead of slapping together some
spaghetti code together, and rely on some convoluted version of garbage
collection to help me debug my code and track down any errors in object
usage.

It's really not that difficult, and is the very essence of "lowest" possible
cost in terms of development and debugging.

>> If I see someone's spaghetti code missing the obvious deletes,
>> in the appropriate places, I ask them about it, and they say
>> "oh, don't worry about, the garbage collector will take care
>> of it", I would not describe such a person as a
>> "professional".
>
> In other words, the more deletes, the more professional.
> Strange definition, to say the least.

Where did you imagine the word "more"?


Sam

unread,
Mar 2, 2008, 11:21:29 PM3/2/08
to
James Kanze writes:

> On 2 mar, 16:56, Sam <s...@email-scan.com> wrote:
>> James Kanze writes:
>> > On 1 mar, 03:11, Sam <s...@email-scan.com> wrote:
>
>> >> >> in order not to run out of available file descriptors.
>
>> >> > In Java, you use try/catch blocks, and in C++, you use
>> >> > destructors.
>
>> >> Whoooooooosh!!! Right over your head.
>
>> > It's becoming more and more apparent that you don't really know
>> > either C++ or Java. In both languages, a file descripter is
>> > freed when you close the file. Nothing to do with garbage
>> > collection.
>
>> It's already apparent that you don't really understand the
>> problems with garbage collection,
>
> Until now, it's been you whose shown an absense of
> understanding---of garbage collection, of program design, of the
> C++ object model. I'm beginning to wonder what you do
> understand.

There is no garbage collection in the "C++ object model", and yes, I plead
guilty to failing to understand completely the incompetence and lack of
experience that would require someone to resort to such an ugly hack in
order to accomplish anything of significance.

>> as it gets clearly demonstrated the Java model,
>
> Java is not C++, and it uses different paradigms. Garbage

Bingo! So, if you want garbage collection, go have fun in Java.

> collection is essential in Java, because all objects must be
> allocated dynamically, and user defined types can't have value
> semantics. It's optional in C++, because we do have value
> semantics. Optional, but it still saves the programmer some
> unnecessary work.

No, it's not "optional" in C++. It does not exist, at all, in C++. Go look
up the "optional" part of ISO/IEC 14882:2003 that defines whatever you think
"garbage collection" means in the C++ context. I eagerly await the results
of your search.

>> and why it forces you to explicitly code exception handling,
>> when dealing with external resources,
>
> The reason you need explict try/catch or try/finally blocks in
> Java is because that's Java's model. In C++, you use
> destructors.

No, you just know even less about Java that you know about C++.

> Garbage collection has absolutely nothing to do with it. The
> absense of on stack objects and destructors is the key
> difference here.

It has everything to do with the garbage collection aspect of Java, and its
impact on external resources.

>> thus defeating the very thing that's touted as Java's
>> advantage of not forcing the programmer to manage the object's
>> lifetimes, and letting the VM take care of it.
>
> Some advertising writers may claim that, but no professional
> programmer, regardless of the language he uses, would pretend
> that you can ignore object lifetimes.

You just admitted, in another message, that "professional" programmers
welcome the opportunity to ignore object lifetimes, just so they can deliver
a product at a "lowest" cost.

Which one is it?

>> I'll spell it out, but just once. You're constructing a java
>> object that contains a java.io.File, as one of its members (or
>> any other object that refers to some external resource). Right
>> after you acquire the external resource (by opening the file,
>> or an equivalent operation on another type of a resource), you
>> must immediately have a try/catch block that will release the
>> external resource if an exception occurs before the object
>> gets completely constructed. Because if one occurs and you
>> don't catch it, then, due to the wonders of the Java VM, that
>> java.io.File object will still exist and claim the external
>> resource, until the VM decides to GC it. So, lather, rinse,
>> repeat, and you're out of file descriptors, since the VM
>> thinks it still has plenty of memory, and it doesn't bother to
>> finalize and collect all the java.io.File objects that are
>> littering the heap.
>
> And why? That's not because of garbage collection---the

It's precisely because of garbage collection. If Java did not use garbage
collection, and finalized and released objects immediately after they went
out of scope, this problem would not exist. Here's some paper and pencil, go
and work it out for yourself.

Sorry to have to confuse you with facts.

> situation would be exactly the same if you created an ofstream
> dynamically, instead of making it a member. The reason is
> because Java doesn't have destructors, nor true member
> subobjects.

Java certain has destructors. Just because you don't know about them,
doesn't mean that they do not exist.

> (Of course, files are a special case, because you wouldn't
> normally close them in a destructor anyway.)

Brilliant!

Listen up folks! You're about to learn something, here! Don't bother to
close those pesky files, in the destructors of objects which own them. Those
files will close by themselves, magically!

You learn something new every day, around here.

>> And you now have to percolate and code the same clumsy
>> exception handling all the way up your class hierarchy, and
>> with anything else that touches any part of this class
>> hierarchy. Your homework assignment is to figure out why.
>
>> There you go, the wonderful advantages of garbage collection,
>> for you.
>
> The problem with all of your arguments is that they have
> absolutely nothing to do with garbage collection.

That straw you're grasping can't last much longer. Not only you're wrong WRT
garbage collection, you don't even fully understand what it means.


Ian Collins

unread,
Mar 2, 2008, 11:51:27 PM3/2/08
to
Sam wrote:
> James Kanze writes:
>> On 2 mar, 16:55, Sam <s...@email-scan.com> wrote: C++.

>
>>> Irrelevant. Whether or not they are separate concepts reflects
>>> nothing on the fact that separating their respective
>>> occurences buys you nothing, or makes any sense.
>>
>> Which doubtlessly explains why in C++ they are completely
>> separated into two separate functions,
>
> Damn right! There's no such thing as "delete", in C++, which handles
> both object destruction and memory release. There's a "foo", that does
> the first part, and "bar", that does the second one. My mistake.
>
Cool down chaps, you are arguing at cross purposes.

I may be completely wrong, but I think James was saying that with
containers (as typified by the STL) of pointers, destroying the
container does not free the memory associated with the pointers. If
(and this may be a big if) the referenced objects have trivial
destructors, garbage collection will mop them up.

No one would dispute deleting an object invokes its destructor and
releases the memory used by the object.

Now I would argue that smart pointers achieve the same result as GC in
that case. I would also argue that smart pointers work equally well
with objects with trivial destructors and objects with non-trivial
destructors, which makes them a better general purpose solution.

I would also go so far as to argue that smart pointers are more
idiomatic C++ than garbage collection. After all, the current standard
provides one (all be it unsuitable for use in containers, I never did
understand that decision) and the next will proved more versatile smart
pointers which are suitable for insertion into standard containers. We
will then have even less reason to use garbage collection with standard
containers.

--
Ian Collins.

Kai-Uwe Bux

unread,
Mar 3, 2008, 12:27:18 AM3/3/08
to
Sam wrote:

> James Kanze writes:
[snip]
>> Garbage
[snip]


>> collection is essential in Java, because all objects must be
>> allocated dynamically, and user defined types can't have value
>> semantics. It's optional in C++, because we do have value
>> semantics. Optional, but it still saves the programmer some
>> unnecessary work.
>
> No, it's not "optional" in C++. It does not exist, at all, in C++. Go look
> up the "optional" part of ISO/IEC 14882:2003 that defines whatever you
> think "garbage collection" means in the C++ context. I eagerly await the
> results of your search.

I don't think that is entirely correct. The C++ standard is worded very
cautiously with regard to new and delete to leave a tremendous amount of
freedom to the implementation. I think, a compliant implementation could
use garbage collection. In particular, I do not know of any language in the
C++ standard that would require the following program to ask the execution
environment for an unbounded amount of memory:

int main ( void ) {
while ( true ) {
new int ( 5 );
}
}


Best

Kai-Uwe Bux

Chris Thomasson

unread,
Mar 3, 2008, 2:22:38 AM3/3/08
to
"James Kanze" <james...@gmail.com> wrote in message
news:ccc9b067-2f0e-41b0...@y77g2000hsy.googlegroups.com...
[...]

> I don't know what a DOM tree is, but I certainly keep pointers
> in containers, and I do pass them between threads. Passing them
> between threads is one case where I do use a smart
> pointer---std::auto_ptr---because once I've handed the object
> off, I don't want to be able to access it again in the
> originating thread. (The objects passed between threads are
> almost always "agents".)

Yeah. You could do a very nice auto_ptr with the XCHG or SWAP/membar (e.g.,
x86/SPARC) instruction(s).

[...]

> If you don't have garbage collection, smart pointers may be
> better than nothing. In some cases. I use all three: raw
> pointers (for pure navigation), garbage collection (for memory
> management) and smart pointers (for special cases like passing
> between threads, or associating a lock with a pointer). If for
> some reason I can't use garbage collection, then I'll also use
> smart pointers to simulate it. But that requires some
> additional effort.

I prefer using a proxy garbage collector. One reason is because I can use
existing C malloc/free API implementations, and have the ability to define
garbage collected regions. Why would I want to use a traditional GC when I
could make clever use of RCU? You can read and ask questions about proxy GC
on 'comp.programming.threads'.

James Kanze

unread,
Mar 3, 2008, 4:40:13 AM3/3/08
to
On Mar 3, 1:37 am, Ioannis Vranos <ivra...@nospam.no.spamfreemail.gr>
wrote:
> James Kanze wrote:

> >>> It has nothing to do with a destructor in the C++ sense,
> >>> and serves a completely different role.

> >> Isn't that what I said?

> > Yes. I wasn't disagreeing with you. Just trying to say it
> > in an even stronger way.

> Leaving "Java" apart, which is a close language syntax +
> virtual machine combination, you may check this regarding
> C++/CLI:

> http://en.wikipedia.org/wiki/C%2B%2B/CLI

> The managed class ("ref class") comes with both a
> deterministic destructor and a non-deterministic destructor
> (called by the GC). If you the managed object reaches the end
> of its scope (the managed objects can be like regular objects
> and not required to be allocated by gcnew), or you delete them
> explicitly if you have created them with gcnew, the
> deterministic destructor is called. If you have allocated the
> managed object with gcnew and you leave it to be garbage
> collected, the non-deterministic destructor is called. I think
> this is a very good approach. At the same time, ISO C++ code
> can be used stand-alone or mixed with managed code.

There are too many "destructors" floating around there to please
me. When discussing such issues, I prefer to use distinct
names: dispose or destruct terminates the lifetime of the
object---regardless of how or where it was allocated, and
finalize is a function which is called by the garbage collector,
when it collects the memory. Concerning finalize, there are two
important points to remember: objects with an explicit disposal
function might not (in fact, shouldn't) be alive when it is
called, and it won't be called on local or static objects.
Calling both destructors just adds to the confusion. (For that
matter, speaking of "destructors" in this context may add to the
confusion, since the word more often applies to a concrete C++
language concept rather than the more general concept.)

> Even at the time I was creating .NET applications with "C++
> managed extensions" where every managed object had to be
> allocated with __gcnew and left to be destroyed by the GC,
> while you could define an explicit function to call so as to
> free allocated resources explicitly when you wanted, and not
> wait for GC to free the resources by calling the Finalizer
> (the non-deterministic destructor that was the only kind of
> destructor for managed classes), leaving all those Forms,
> Buttons etc to the GC was a great relief, not having to worry
> about explicitly releasing all those stuff.

Exactly. It's not something that is fundamentally necessary
(but then, neither are classes), but it's something that means
less work for the programmer, in the cases where it's
applicable. The cases where it's applicable are frequent
enough to justify adding it to the language, and offering it as
an add on isn't always a viable option. (To be really
effective, for example, the standard library must be GC aware,
with e.g. std::string using garbage collection, std::vector
null'ing freed elements, etc.)

> So I think in normal PC GUI applications,garbage collection
> has a place to make the programmer's life easier, where space
> efficiency is not a primary concern (that is for the usual
> user applications).

> I remember some company or MS had ported Quake II to .NET and
> the runt-time cost was only about 10%. So even Quake II where
> speed is a primary concern, the GC didn't cause much trouble,
> but rather it helped much.

GC is almost always a win in interactive software, since it will
run while you're waiting for user input. (This is also possible
with manual management, but it's not usually done. I don't know
why.) GC is also particularly effective when you have a lot of
short lived objects, which is, I suspect, typical of games
programs (although I'm not sure---I've never actually worked on
them).

> GC has a place in the present and in the future, I think all
> must come in terms with that. We can't stick in the past,
> technology is moving forward. If you like it, use it, if you
> don't like it, don't use it.

Yes. In practice, the C++ committee is at a juncture.
Independantly of any technical considerations, if the next
version of the standard doesn't support garbage collection and
threads, C++ is dead in the water---it will end up in the same
state as C, with a lot of older people used to it who continue
to use it, and argue in favor of it, because it's what they
know, but with less and less new applications being implemented
in it. (Alternatively, the major compiler vendors will simply
copy Microsoft, implement CLI, and call it C++. And the ISO
standard becomes irrelevant. And that's not a scenario I want
to see.)

James Kanze

unread,
Mar 3, 2008, 5:05:19 AM3/3/08
to
On Mar 3, 1:20 am, Ian Collins <ian-n...@hotmail.com> wrote:
> James Kanze wrote:
> > On 2 mar, 19:17, Ian Collins <ian-n...@hotmail.com> wrote:
> >> James Kanze wrote:
> >>> On 1 mar, 06:23, Ian Collins <ian-n...@hotmail.com> wrote:
> >>>> But how does a user know if an object has to be deleted,
> >>>> or whether it can be left to the GC?

> >>> Maybe because he knows what the object is used for, and
> >>> why he created it in the first place?

> >> But he'd have to whether the object had to be deleted, or
> >> could be left for the GC.

> > Certainly. But that's always the case. You don't create
> > objects without knowing the role of the object, or what it's
> > there for.

> But why add yet another facet?

I'm afraid I don't understand. I'm not adding anything. It's
all already there. About the only thing I'm suggesting is to
separate concerns, so the program can worry about each
separately, without being concerned about the other if it's not
relevant. (Note that there are special cases already where you
separate these concerns. It's an underlying principle in the
containers in the standard library, for example, where
initialization and allocation, as well as destruction and
deallocation, are rigorously separated.)

> >>>> It's the ambiguity with C++ I don't like, especially as
> >>>> C++ provides language features that make GC an
> >>>> irrelevance.

> >>> Not an irrelevance. Less important, but programmer
> >>> productivity is never really irrelevant.

> >> I still contend that correct and systematic use of smart
> >> pointers does make GC an irrelevance without any sacrifice
> >> in productivity.

> > It adds to the programmer work load. It's more code you have to
> > write.

> No, once written, smart pointer types can be used just like
> any other, no extra work at all. One may have to choose which
> type to use and there is always the risk of getting it wrong.

And you don't see a contradition in those two sentences? In my
work, most pointers are for navigation, and the navigational
possibilities are full of cycles. Using smart pointers
systematically would involve a great deal of extra analysis.
(Of course, in this context, there is no problem with regards to
when to delete the objects, and the garbage collection is mainly
a safety net, to allow trapping the use of a dangling pointer,
and not really necessary for reasons of memory management.)

There are other contexts where boost::shared_ptr (or my
pre-boost shared pointers) do work well, but again, I have to
think about them---I've identified the fact that the objects
don't need deterministic disposal (otherwise, I can't use
boost::shared_ptr), but I still have to consider possible
cycles, etc. It's not overwhelming, but it is a little bit of
extra work.

> But the same could happen with a mix of GC and user managed
> objects.

You can always neglect to correctly terminate the life of an
object. I've never found it to be a frequent problem,
however---less frequent than correctly handling some other major
events in the object lifetime. And boost::shared_ptr doesn't
really help, since you're likely to still have a pointer to the
object.

A more frequent problem is dangling pointers: the object's
lifetime has ended, but you've neglected to inform an interested
party. Garbage collection makes it easy to check for this,
whenever you use the pointer. (You can also make it work with a
combination of shared_ptr and weak_ptr, but it requires more
effort.)

> As I said before, it's not GC I object to, it's mixing GC and
> "conventional" memory management.

You don't mix them. All memory management is by garbage
collection.

> I'd also object the mixing raw pointers with smart pointers
> for dynamic objects.

In which case, you'll never use smart pointers, because there
just aren't enough different types of them to handle all of the
cases. (Unless you create a smart pointer which really does
nothing, for navigational purposes.)

> >>> I tried that, and gave up with it. It resulted in too many
> >>> memory leaks. In my applications, most pointers are used for
> >>> navigation, not for ownership. And raw pointers work perfectly
> >>> well for navigation.

> >> Ah, well that's where our domains differ. Most of the places where I
> >> would have used pointers are in containers, manipulating DOM trees or
> >> for passing objects between threads.

> > I don't know what a DOM tree is

> The Document Object Model. I do a lot of work with XML and
> XHTML documents!

Oops. I've actually used it, both in Java and in C++. I just
didn't recognize the name right off.

Richard Herring

unread,
Mar 3, 2008, 7:08:03 AM3/3/08
to
In message <cone.1204327480....@commodore.email-scan.com>,
Sam <s...@email-scan.com> writes

>Richard Herring writes:
>
>> In message
>><cone.1204246382...@commodore.email-scan.com>, Sam
>><s...@email-scan.com> writes
>>>Sebastian Nibisz writes:
>>>
>>>>> Garbage collection is for lazy rich folks who can't be bothered to
>>>>> take out their own trash.
>>>> It's funny.
>>>
>>>It's true. If you do not have the skills and the know-how to keep
>>>track of your own objects, and manage their lifetime,
>> ... or if you think garbage collection is about lifetime management
>>...

>
>Let me know when you figure out why, in Java, you have to throw all
>these try/catch blocks around, every time you need to deal with files
>or sockets, in order not to run out of available file descriptors.

Maybe that would be because garbage collection is for recycling memory,
not for managing the lifetime of external resources.

Next?

>So much for garbage collection.

So much for using garbage collection for lifetime management, indeed.

--
Richard Herring

It is loading more messages.
0 new messages