468,463 Members | 2,026 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,463 developers. It's quick & easy.

Garbage Collection in C

Abstract
--------
Garbage collection is a method of managing memory by using a "collector"
library. Periodically, or triggered by an allocation request, the
collector looks for unused memory chunks and recycles them.
This memory allocation strategy has been adapted to C (and C++) by the
library written by Hans J Boehm and Alan J Demers.

Why a Garbage Collector?
-----------------------
Standard C knows only the malloc/calloc/free functions. The programmer
must manage each block of memory it allocates, never forgetting to call
the standard function free() for each block. Any error is immediately
fatal, but helas, not with immediate consequences. Many errors like
freeing a block twice (or more) or forgetting to free an allocated
block will be discovered much later (if at all). This type of bugs are
very difficult to find and a whole industry of software packages
exists just to find this type of bugs.

The garbage collector presents a viable alternative to the traditional
malloc/free "manual" allocation strategies. The allocator of Boehm
tries to find unused memory when either an allocation request is
done, or when explicitely invoked by the programmer.

The main advantage of a garbage collector is that the programmer is
freed from the responsability of allocating/deallocating memory. The
programmer requests memory to the GC, and then the rest is *automatic*.
Limitations of the GC.
---------------------
The GC needs to see all pointers in a program. Since it scans
periodically memory, it will assume that any block in its block list is
free to reuse when it can't find any pointers to it. This means that the
programmer can't store pointers in the disk, or in the "windows extra
bytes", as it was customary to do under older windows versions, or
elsewhere.

This is actually not a limitation since most programs do not write
pointers to disk, and expect them to be valid later...
Obviously, there is an infinite way to hide pointers (by XORing them
with some constant for instance) to hide them from the collector.

This is of no practical significance. Pointers aren't XORed in normal
programs, and if you stay within the normal alignment requirements
of the processor, everything works without any problems.

Performance considerations
--------------------------
In modern workstations, the time needed to make a complete sweep in
mid-size projects is very small, measured in some milliseconds. In
programs that are not real time the GC time is completely undetectable.
I have used Boehm's GC in the IDE of lcc-win32, specially in the
debugger. Each string I show in the "automatic" window is allocated
using the GC. In slow machines you can sometimes see a pause of
less than a second, completely undetectable unless you know that is
there and try to find it.

It must be said too that the malloc/free system is slow too, since at
each allocation request malloc must go through the list of free blocks
trying to find a free one. Memory must be consolidated too, to avoid
fragmentation, and a malloc call can become very expensive, depending
on the implementation and the allocation pattern done by the program.
Portability
-----------
Boehm's GC runs under most standard PC and UNIX/Linux platforms. The
collector should work on Linux, *BSD, recent Windows versions, MacOS X,
HP/UX, Solaris, Tru64, Irix and a few other operating systems. Some
ports are more polished than others. There are instructions for porting
the collector to a new platform. Kenjiro Taura, Toshio Endo, and Akinori
Yonezawa have made available a parallel collector.

Conclusions
-----------
The GC is a good alternative to traditional allocation strategies for C
(and C++). The main weakness of the malloc/free system is that it
doesn't scale. It is impossible to be good at doing a mind numbing task
without any error 100% of the time. You can be good at it, you can be
bad at it, but you can NEVER be perfect. It is human nature.

The GC frees you from those problems, and allows you to conecntrate in
the problems that really matter, and where you can show your strength
as software designer. It frees you from the boring task of keeping track
of each memory block you allocate.

jacob

Oct 11 '06
142 5137
In article <78*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.comwrote:
>Even something as primitive as the following should work
As I think you must know, that's not garbage collection in the sense
being discussed.

-- Richard
Oct 12 '06 #51
Richard Tobin posted:
In article <78*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.comwrote:
>>Even something as primitive as the following should work

As I think you must know, that's not garbage collection in the sense
being discussed.

I haven't been following the discussion much (as I've no use for garbage
collection), nor have I read up on the topic... so I just presumed it had
something to do with automatic-freeing of allocated memory.

--

Frederick Gotham
Oct 12 '06 #52

Frederick Gotham wrote:
William Hughes posted:
It's simple to write a fully-portable GC.
Which wasn't the question.
It doesn't matter if the GC is written in a combination of
assembler and Lithp ( a programming language that the Igors
use to process lithtths). The question is whether it will
work on any conforming program.
This includes a program that allocates some memory,
xor's a pointer twice with the same string, and
then uses the memory.

Why do think it might not work? I don't see any barriers.

Because either the garbage collector would free the memory
after the first xor, in which case it breaks the program,
or the garbage collector would not free the memory after
the first xor in which case either the GC is not a garbage
collector in any useful sense of the term, or the GC is
so smart that I will let it write the program.

- William Hughes

Oct 12 '06 #53
Default User <de***********@yahoo.comwrote:
jacob navia wrote:
>[inflammatory off-topic crap]
Ok, that's finally enough for a plonk.
I will join you, only because the skirmishes he tends to instigate are
quite tiresome to wade through. Richard is too valuable of a poster
to plonk, so I will settle for reading the better half of the ongoing
Hatfield/McCoy battles.

--
C. Benson Manica | I *should* know what I'm talking about - if I
cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
Oct 12 '06 #54
jacob navia wrote:
Roland Pibinger wrote:
On Wed, 11 Oct 2006 18:52:54 +0200, jacob navia wrote:
>Conclusions
-----------
The GC is a good alternative to traditional allocation strategies for C
(and C++).

GC is incompatible with C++ (destructors) and inappropriate for the
system programming language C (you didn't even mention the huge memory
overhead of GC).

Why should the destructors be touched? They just
do not call free() (delete in C++) and that is it.
<OT>
Code that relies on objects being destroyed at a specific point is very
common in C++ (e.g. the standard C++ library). GCs don't guarantee
*when* objects are deallocated, only that they do eventually get
deallocated. BTW, that's the reason Java has a 'finally' clause instead
of destructors.
</OT>

Regards,
Bart.

Oct 12 '06 #55
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <11**********************@c28g2000cwb.googlegroups .com>,
William Hughes <wp*******@hotmail.comwrote:
>>The question is whether it will
work on any conforming program.
This includes a program that allocates some memory,
xor's a pointer twice with the same string, and
then uses the memory.

In order to xor a pointer with anything, you would need to
convert the pointer into an integral value, then convert the
integral value to a pointer and have the resulting pointer compare
equal to the original pointer.
[...]

You can extract the representation of the pointer by aliasing or
memcpy()ing it to an appropriately sized array of unsigned char.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 12 '06 #56
Bart wrote:
jacob navia wrote:
>>Roland Pibinger wrote:
>>>On Wed, 11 Oct 2006 18:52:54 +0200, jacob navia wrote:
Conclusions
-----------
The GC is a good alternative to traditional allocation strategies for C
(and C++).
GC is incompatible with C++ (destructors) and inappropriate for the
system programming language C (you didn't even mention the huge memory
overhead of GC).

Why should the destructors be touched? They just
do not call free() (delete in C++) and that is it.


<OT>
Code that relies on objects being destroyed at a specific point is very
common in C++ (e.g. the standard C++ library). GCs don't guarantee
*when* objects are deallocated, only that they do eventually get
deallocated. BTW, that's the reason Java has a 'finally' clause instead
of destructors.
</OT>

Regards,
Bart.
You misunderstand. The object *IS* destroyed. Only its storage is
not reclaimed. The destructor is called as the C++ rules want. It just
doesn't call delete.
Oct 12 '06 #57
jacob navia wrote:
Bart wrote:
jacob navia wrote:
>Roland Pibinger wrote:

On Wed, 11 Oct 2006 18:52:54 +0200, jacob navia wrote:
Conclusions
-----------
The GC is a good alternative to traditional allocation strategies for C
(and C++).
GC is incompatible with C++ (destructors) and inappropriate for the
system programming language C (you didn't even mention the huge memory
overhead of GC).
Why should the destructors be touched? They just
do not call free() (delete in C++) and that is it.

<OT>
Code that relies on objects being destroyed at a specific point is very
common in C++ (e.g. the standard C++ library). GCs don't guarantee
*when* objects are deallocated, only that they do eventually get
deallocated. BTW, that's the reason Java has a 'finally' clause instead
of destructors.
</OT>

Regards,
Bart.

You misunderstand. The object *IS* destroyed. Only its storage is
not reclaimed. The destructor is called as the C++ rules want. It just
doesn't call delete.
So how is the object destroyed? I have to actually put a delete
statement in my program. Talk about garbage collection. Way to go!

Regards,
Bart.

Oct 12 '06 #58
Walter Roberson wrote:
In article <11**********************@c28g2000cwb.googlegroups .com>,
William Hughes <wp*******@hotmail.comwrote:
>The question is whether it will
work on any conforming program.
This includes a program that allocates some memory,
xor's a pointer twice with the same string, and
then uses the memory.

In order to xor a pointer with anything, you would need to
convert the pointer into an integral value, then convert the
integral value to a pointer and have the resulting pointer compare
equal to the original pointer.

C89 and C99 allow implementations to define casting pointers to and
from integral values, but does not define the meaning of that
conversion. C99 promises that the conversion is reversable, but C89
does not (but K&R2 does.)
No, you do not have to do that. You can treat it as an unsigned char
array and do it that way.
--
Flash Gordon
Oct 12 '06 #59
Kenny McCormack wrote:
Anyway, Jacob, why do you punish yourself so? Why do you go around with
a kick-me sign on your backside? You could state that 2+2 = 4 and
heathfield would say it isn't so. That's just what it is.
Well, 2+2 is not an lvalue, so you can't assign 4 to it. ;-)

--
Simon.
Oct 12 '06 #60
Al Balmer wrote:
CBFalconer <cb********@yahoo.comwrote:
>Richard Heathfield wrote:
>>jacob navia said:

Why a Garbage Collector?
-----------------------
Standard C knows only the malloc/calloc/free functions.

Quite so. Please move discussions of non-C matters to some other
newsgroup where it is topical.

I think this particular carp is unfair. Jacob has been
fundamentally advertising the available of the Boehm library for
GC, which I presume is written in standard C, or nearly so.

That doesn't make it topical. He's discussing the product, not the
code. As we keep reminding people here, the fact that a program is
written in C doesn't make discussion of the program itself topical.
I looked back at the original post. He doesn't mention his product
(lcc-win32) once in the article. I think he made an effort to
comply with topicality here, while still recommending the use of
such a library, and think that this is fair. The fact is that his
previous off-topic insistence have colored the reaction to anything
he posts, and I think we should lean over backwards to accept
topical (or even nearly topical) posts from him.

We can, and should, criticize the actual portability of the
library. I have not looked at the code involved, so cannot really
comment on that aspect.

As I have posted elsethread (or is it elsegroup?) I feel free to
advertise the availability of my nmalloc system [1], which is not
completely portable, but does list the requirements of the
underlying system. No malloc system can be totally portable, and
thus no GC system can be either. This does not make such systems
uninteresting. As a fairly well known USAnian once said: "you
gotta know your limitations".

As a further example I often include the following code in my
applications, enabling automatic help when run with no parameters:

/* This is very likely to be non-portable
DOES NOT check fp open for reading
NULL fp is considered a keyboard here!
With "gcc -W -Wall -ansi -pedantic" we can expect
implicit declaration warnings for isatty and fileno.
However the result should link correctly.
If it always returns 0 the system still works
but will not give the automatic help.
*/
static int akeyboard(FILE *fp)
{
#ifndef __TURBOC__ /* TC2 is peculiar */
# ifdef __STDC__
/* This dirty operation allows gcc -ansi -pedantic */
extern int fileno(FILE *fp);
extern int isatty(int fn);
# endif
#endif
return ((fp != NULL) && isatty(fileno(fp)));
} /* akeyboard */

This returns false if stdin has been redirected, on most systems.
It is easily replaced at the cost of the automatic help feature. I
don't feel shy about using it in otherwise portable programs. It
also makes the automatic assumption that the default connection for
stdin is a keyboard.

[1] Aside to Jacob: You are perfectly free to incorporate nmalloc
in the lcc-win32 library if you wish. It also provides a fairly
well tested user debugging mechanism, and a way to extract the
essential parameters of the malloc system in a standard conforming
manner. This provides all the hooks needed (IMO) to implement GC
on the systems of interest to you. It should be possible to
dynamically switch such a GC system on and off with it.

--
Some informative links:
<news:news.announce.newusers
<http://www.geocities.com/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/>
Oct 12 '06 #61

"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
jacob navia <ja***@jacob.remcomp.frwrites:
[snip]
>Performance considerations
--------------------------
In modern workstations, the time needed to make a complete sweep in
mid-size projects is very small, measured in some milliseconds. In
programs that are not real time the GC time is completely undetectable.
I have used Boehm's GC in the IDE of lcc-win32, specially in the
debugger. Each string I show in the "automatic" window is allocated
using the GC. In slow machines you can sometimes see a pause of
less than a second, completely undetectable unless you know that is
there and try to find it.

A pause of "less than a second" isn't necessarily going to be a
problem for an interactive program like an IDE. It could be fatal for
more time-sensitive applications. Again, you acknowledge the problem,
but you seem to assume that since it's not an issue for you, it's not
going to be an issue for anyone.
relatively long and unpredictable pauses are unaccceptable for some
aplications (e.g. trading systems, any time-critical control:
air-traffic-control, nuclear-power-station, DSP, video) Traditional GC
systems have delays in stop-and-copy garbage collection and, even modern
generational scavenging GC has delays. (BTW certain modern object oriented
languages have claimed garbage collection to be part of OO - garbage
collection was invented by the pure functional programing languages)

in C garbage collection is done through the free function - the problems
with the misuse of free are that a programmer can forget to free memory (a
"memory leak") or can free memory that is still being used.
Oct 12 '06 #62
On Thu, 12 Oct 2006 16:31:34 -0400, CBFalconer <cb********@yahoo.com>
wrote:
>That doesn't make it topical. He's discussing the product, not the
code. As we keep reminding people here, the fact that a program is
written in C doesn't make discussion of the program itself topical.

I looked back at the original post. He doesn't mention his product
Neither did I.
>(lcc-win32) once in the article. I think he made an effort to
comply with topicality here,
If so, IMO, he failed. Unless you consider that refraining from
advertising his own product was such an effort ;-)
while still recommending the use of
such a library, and think that this is fair.
--
Al Balmer
Sun City, AZ
Oct 13 '06 #63
Paul Connolly wrote:
(BTW certain modern object oriented
languages have claimed garbage collection to be part of OO - garbage
collection was invented by the pure functional programing languages)
So the assignment-free model is really a myth?
Oct 13 '06 #64
# Well, this is NON-STANDARD. As far as C is concerned, a subtracting
# one from the start of an object is undefined behavior.

The Boehm-Demers collector does not expect assistance
from the compiler or runtime system and so depend
writing programs which are restricted from the full power
of C (standard or other).

Some programs dedicated to the efficiency goddess Dierdre
(who shares an apartment with the software engineering
goddess Eris) will crash and burn spectacularly with a
Boehm-Demers collector. Luckily the restrictions on the
language are easy, reasonable, and drive program development
towards more comprehensible code. Your kilometrage may vary.

Otherwise most of the horror stories of GC are false.
I guess if you're dealing 65KB 8bit single bit CPU
running embedded toaster or ICBM code, GC would be
a mismatch, but I don't write that kind of code anymore.

At least not since that incident in northern Ukraine.

I realized on one project roughly a third of the code
was spent solely on tracking live pointers and collecting
complex data storage. I switched to B-D GC and haven't
looked back.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
So basically, you just trace.
Oct 13 '06 #65
Paul Connolly wrote:
relatively long and unpredictable pauses are unaccceptable for some
aplications (e.g. trading systems, any time-critical control:
air-traffic-control, nuclear-power-station, DSP, video) Traditional GC
systems have delays in stop-and-copy garbage collection and, even modern
generational scavenging GC has delays. (BTW certain modern object oriented
languages have claimed garbage collection to be part of OO - garbage
collection was invented by the pure functional programing languages)
I believe Lisp had destructive update when it acquired GC, but I
could be wrong.

--
Chris "Essen -6 and counting" Dollin
The "good old days" used to be much better.

Oct 13 '06 #66
jmcgill wrote:
Paul Connolly wrote:
>(BTW certain modern object oriented
languages have claimed garbage collection to be part of OO - garbage
collection was invented by the pure functional programing languages)

So the assignment-free model is really a myth?
The /languages/ don't have assignment. The /implementation/ may use
it underneath.

--
Chris "Essen -6 and counting" Dollin
"No-one here is exactly what he appears." G'kar, /Babylon 5/

Oct 13 '06 #67
Chris Dollin wrote:
Paul Connolly wrote:
>relatively long and unpredictable pauses are unaccceptable for some
aplications (e.g. trading systems, any time-critical control:
air-traffic-control, nuclear-power-station, DSP, video) Traditional GC
systems have delays in stop-and-copy garbage collection and, even modern
generational scavenging GC has delays. (BTW certain modern object oriented
languages have claimed garbage collection to be part of OO - garbage
collection was invented by the pure functional programing languages)

I believe Lisp had destructive update when it acquired GC, but I
could be wrong.
I believe Lisp always had GC. Some implementations may not have.

--
Some informative links:
<news:news.announce.newusers
<http://www.geocities.com/nnqweb/>
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/>

Oct 13 '06 #68
In article <12*************@corp.supernews.com>,
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrote:
>I guess if you're dealing 65KB 8bit single bit CPU
running embedded toaster or ICBM code, GC would be
a mismatch, but I don't write that kind of code anymore.
But if you're running a Lisp interpreter on that hardware (or even
with 32KB), garbage collection is (or was) quite practical. Probably
not written in C though.

-- Richard
Oct 13 '06 #69
In article <h_BXg.1256$rS.382@fed1read05>,
jmcgill <jm*****@email.arizona.eduwrote:
>(BTW certain modern object oriented
languages have claimed garbage collection to be part of OO - garbage
collection was invented by the pure functional programing languages)
>So the assignment-free model is really a myth?
Where does assignment come into it? Memory can be allocated and
become garbage without any assignments.

-- Richard
Oct 13 '06 #70
CBFalconer wrote:
Chris Dollin wrote:
>Paul Connolly wrote:
>>relatively long and unpredictable pauses are unaccceptable for some
aplications (e.g. trading systems, any time-critical control:
air-traffic-control, nuclear-power-station, DSP, video) Traditional GC
systems have delays in stop-and-copy garbage collection and, even modern
generational scavenging GC has delays. (BTW certain modern object oriented
languages have claimed garbage collection to be part of OO - garbage
collection was invented by the pure functional programing languages)

I believe Lisp had destructive update when it acquired GC, but I
could be wrong.

I believe Lisp always had GC. Some implementations may not have.
So a quick Google got me http://www.iwriteiam.nl/HaCAR_CDR.html,
from which I extract:

Email from Steve Russell
I wrote the first implimenation of a LISP interpreter on the IBM 704
at MIT in early in 1959. I hand-compiled John McCarthy's "Universal
LISP Function".

and

As the 704 has 36 bit words, there were 6 bits in the list nodes
that were not used. Our initial implimentation did not use them at
all, but the first garbage collector, comissioned in the summer of 1959,
used some of them as flags.

which I read as saying the the first implementation had no GC, but
that it was added very shortly afterwards. However, my googlefu is
not sufficient to determine whether Lisp started with set, setcar,
and setcdr or not. If it did, destructive assignment in Lisp preceeded
garbage collection, and hence GC wasn't "invented by the pure functional
programing languages": otherwise, it was.

Further discussion best done off-list, I think. If someone
finds a link for a sufficiently early description of Lisp, I'd
be grateful.

--
Chris "Essen -6 and counting" Dollin
"A facility for quotation covers the absence of original thought." /Gaudy Night/

Oct 13 '06 #71
Paul Connolly wrote:
relatively long and unpredictable pauses are unaccceptable for some
aplications (e.g. trading systems, any time-critical control:
air-traffic-control, nuclear-power-station, DSP, video) Traditional GC
systems have delays in stop-and-copy garbage collection and, even modern
generational scavenging GC has delays.
_Some_ traditional GC systems have noticeable delays (e.g mark-sweep
and copy collect). Reference counting has a long tradition and can be
done with real-time guarantees.

More recently, things like Treadmill and Bacon's algorithm offer more
sophisticated real-time GC.

Apropos to the original post, Boehm offers incremental collection to
try to reduce latencies; that's quite nice for interactive
applications, but it's not a real-time solution.

Oct 13 '06 #72
sj*******@yahoo.com wrote:
Paul Connolly wrote:
>relatively long and unpredictable pauses are unaccceptable for some
aplications (e.g. trading systems, any time-critical control:
air-traffic-control, nuclear-power-station, DSP, video) Traditional GC
systems have delays in stop-and-copy garbage collection and, even modern
generational scavenging GC has delays.

_Some_ traditional GC systems have noticeable delays (e.g mark-sweep
and copy collect). Reference counting has a long tradition and can be
done with real-time guarantees.
Bearing in mind that when the last reference to eg a long linked list
is lost, there will be O(length) work done as each dying reference
decrements to 0 and frees the next item.

Not to disparage reference counting, just as a note that no technique
is without its gotchas.

(Also there are delays and DELAYS; I remember the contrast between
two different common lisps on the same hardware: the configuations
of these were such that one would moderately often pause for about
a tenth of a second, just noticable while editing, while the other
would pause much left often, but for about 90seconds at a time.
I strongly suspect that its heap size exceeded the ram size and
that it fell foul of frashing. I mean thrashing. Too long ago to
find out now.)

--
Chris "Essen -6 and counting" Dollin
"- born in the lab under strict supervision -", - Magenta, /Genetesis/

Oct 13 '06 #73
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
>In order to xor a pointer with anything, you would need to
convert the pointer into an integral value, then convert the
integral value to a pointer and have the resulting pointer compare
equal to the original pointer.
>You can extract the representation of the pointer by aliasing or
memcpy()ing it to an appropriately sized array of unsigned char.
Can you? I'm not completely awake yet, but I can't seem to find
a justification for that in C89.

Aliasing via a union: C89 says that it is only defined if the
two elements are part of a common prefix of identical element types.

Type punning via a pointer cast: C89 talks about casting pointers
to and from other types and the circumstances under which the
double-converted result will compare the same as the original.

It does say that when casting pointer types, that the new
pointer might not be valid if the new type pointed to has a
stricter alignment. As char has the least strict alignment
and unsigned char is promised to have the same alignment as
char, that clause could potentially be construed as implying
that the cast pointer to unsigned char would be valid: but
if one takes that interpretation, then the implication would
be that casting a pointer to double into a pointer to short int
into a pointer to short int is going to produce valid results
because short int has alignment requirements no stricter than double.

Any pointer may be converted to pointer to void, and pointer
to void must (in C89) have the same alignment and representation
as pointer to char, but as per the above, it doesn't follow that
the chars (or unsigned chars) are meaningfully accessible.

I seem to recall that unsigned char shall have no padding and
no trap states (but that that is not promised for char or signed char),
so doing the cast to pointer to unsigned char and pulling out the
unsigned char elements is not going to fault -- but is it promised
that the unsigned char values pulled out must be the same as the
bytes of the original pointer representation? Perhaps that is the
logical implication through a good sequence of reasoning, but is
there chapter & verse that ensures that it is so?
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Oct 13 '06 #74
Frederick Gotham schrieb:
William Hughes posted:
>>It's simple to write a fully-portable GC.
Which wasn't the question.
It doesn't matter if the GC is written in a combination of
assembler and Lithp ( a programming language that the Igors
use to process lithtths). The question is whether it will
work on any conforming program.
This includes a program that allocates some memory,
xor's a pointer twice with the same string, and
then uses the memory.

Why do think it might not work? I don't see any barriers.
Because variables/pointers might be stored in registers. You have to check
the registers of the machine to be sure, that you don't forget any pointer.
This can't be done fully-portable.
Even something as primitive as the following should work, although "gc.h"
would have to be included _after_ all Standard headers.
[snip malloc-replacement that frees memory at exit]

That is no garbage collector.

Guess a normal C programm that works as a web, mail or file server, that
runs 24 hours 365 days a year. This programm will never exit unless some
administrator thinks that it's time to reboot the machine.
Sooner or later the programm will crash since it owns all memory.

--
Thomas
http://www.netmeister.org/news/learn2quote.html
Oct 14 '06 #75
In article <21*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.comwrote:
>I haven't been following the discussion much (as I've no use for garbage
collection), nor have I read up on the topic... so I just presumed it had
something to do with automatic-freeing of allocated memory.
Well yes, but the idea is to free it in time for it to be used by other
malloc()s in the same program!

Something like your code can be used effectively in some cases:
you can record all the memory allocated for some purpose, and
free it when that purpose is complete.

-- Richard
Oct 14 '06 #76

jacob navia wrote:
This means that the
programmer can't store pointers .. in the "windows extra
bytes", as it was customary to do under older windows versions...
It sounds as though you could have the answer to a question of mine. If
people used to store pointers in the extra bytes, but don't do that any
more, what do they do now?

My situation is that I want to find out, when the user does something
to a window, which object is associated with that window. See my post
"Finding the "owner" of a window" in
comp.os.ms-windows.programmer.win32 for more background.

Of course, my question is off-topic on clc, perhaps you might consider
replying to the above post?

Thanks in advance.
Paul.

Oct 15 '06 #77
gw****@aol.com said:
>
jacob navia wrote:
>This means that the
programmer can't store pointers .. in the "windows extra
bytes", as it was customary to do under older windows versions...

It sounds as though you could have the answer to a question of mine. If
people used to store pointers in the extra bytes, but don't do that any
more, what do they do now?
We store pointers in the extra bytes. :-)

Just because Jacob Navia says something, that don't necessarily make it so.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 15 '06 #78
gw****@aol.com wrote:
jacob navia wrote:
This means that the
programmer can't store pointers .. in the "windows extra
bytes", as it was customary to do under older windows versions...

It sounds as though you could have the answer to a question of mine. If
people used to store pointers in the extra bytes, but don't do that any
more, what do they do now?

My situation is that I want to find out, when the user does something
to a window, which object is associated with that window. See my post
"Finding the "owner" of a window" in
comp.os.ms-windows.programmer.win32 for more background.

Of course, my question is off-topic on clc, perhaps you might consider
replying to the above post?
A lot of things in Windows are done by passing pointers to APIs (even
casting them to integers sometimes) and getting them back later through
callbacks. Obviously, the program doesn't hold those pointers in the
mean time. For such uses this GC is quite limiting.

Regards,
Bart.

Oct 16 '06 #79
Bart wrote:
gw****@aol.com wrote:
>>jacob navia wrote:

>>>This means that the
programmer can't store pointers .. in the "windows extra
bytes", as it was customary to do under older windows versions...

It sounds as though you could have the answer to a question of mine. If
people used to store pointers in the extra bytes, but don't do that any
more, what do they do now?

My situation is that I want to find out, when the user does something
to a window, which object is associated with that window. See my post
"Finding the "owner" of a window" in
comp.os.ms-windows.programmer.win32 for more background.

Of course, my question is off-topic on clc, perhaps you might consider
replying to the above post?


A lot of things in Windows are done by passing pointers to APIs (even
casting them to integers sometimes) and getting them back later through
callbacks. Obviously, the program doesn't hold those pointers in the
mean time. For such uses this GC is quite limiting.

Regards,
Bart.
Note that if the APIs are part of some DLLs the GC will see them anyway.
Casts to integers do not affect the GC at all.
Oct 16 '06 #80
gw****@aol.com wrote:
jacob navia wrote:

>>This means that the
programmer can't store pointers .. in the "windows extra
bytes", as it was customary to do under older windows versions...


It sounds as though you could have the answer to a question of mine. If
people used to store pointers in the extra bytes, but don't do that any
more, what do they do now?

My situation is that I want to find out, when the user does something
to a window, which object is associated with that window. See my post
"Finding the "owner" of a window" in
comp.os.ms-windows.programmer.win32 for more background.

Of course, my question is off-topic on clc, perhaps you might consider
replying to the above post?

Thanks in advance.
Paul.
All these extra bytes stuff can be simulated with an associative
list where you just keep a correspondence of window handle and
pointer to the data:

typedef struct tagAssocList {
struct tagAssocList *Next;
void *pData;
void *WindowHandle;
} ASSOCIATIVE_LIST;

And you are all set.

Oct 16 '06 #81
Richard Heathfield wrote:
gw****@aol.com said:

>>jacob navia wrote:

>>>This means that the
programmer can't store pointers .. in the "windows extra
bytes", as it was customary to do under older windows versions...

It sounds as though you could have the answer to a question of mine. If
people used to store pointers in the extra bytes, but don't do that any
more, what do they do now?


We store pointers in the extra bytes. :-)

Just because Jacob Navia says something, that don't necessarily make it so.
You are like a 8 year old...

I see perfectly that you left out the "windows" in your
sentence above...

You lost heathfield. Start again :-)

jacob
Oct 16 '06 #82
jacob navia said:
Richard Heathfield wrote:
>>
Just because Jacob Navia says something, that don't necessarily make it
so.

You are like a 8 year old...
How ironic.
I see perfectly that you left out the "windows" in your
sentence above...
So? It was implied.
You lost heathfield.
You always say that. One day, it might even be true. But not today.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Oct 16 '06 #83
gw****@aol.com wrote:
jacob navia wrote:
This means that the
programmer can't store pointers .. in the "windows extra
bytes", as it was customary to do under older windows versions...

It sounds as though you could have the answer to a question of mine. If
people used to store pointers in the extra bytes, but don't do that any
more, what do they do now?
They store pointers to the pointers. Sometimes they call these "handles"
(which actually are pointers underneath, last time I looked, but of
course this could've changed in the mean time), and sometimes they do
not.
To C, of course, a memcpy() of a pointer works just as well as a
memcpy() of an unsigned long, provided there's memory enough for either.
If you want to add extra limitations to your program by adding a
not-quite-good-enough library, that's the problem of neither ISO C nor
MS Windows.

Richard
Oct 16 '06 #84
In article <45**********************@news.orange.fr>,
jacob navia <ja***@jacob.remcomp.frwrote:
>Note that if the APIs are part of some DLLs the GC will see them anyway.
That statement is vacuously true, since if the number of DLLs that the
GC would pay attention to is precisely zero, that would still be
"some DLLs".

Are you talking about some -particular- DLLs? Are you saying that
the particular GC library you mentioned is able to locate pointers
properly throughout -all- DLLs? Throughout all DLLs specially compiled
with the library??

Your original posting mentioned a number of operating systems, most
of which don't have *any* DLLs. For example, the IRIX operating system
mentioned does not have DLLs (it has DSOs, Dynamic Shared Objects,
but those don't appear to have the same connotations; Windows uses
lots of DLLs, but DSOs are not used particularily often with IRIX,
at least not "Dynamic"-ally.)
>Casts to integers do not affect the GC at all.
Amazing. How does the GC deal with the fact that on a number of
systems, pointers are 64 bits, but 'int' is only 32 bits ?
And how does it deal with representation changes that can occur
when casting pointers? About all the C89 standard promises is that

a) any object pointer may be converted to void*

b) void* and char* have the same alignment and representation

c) casting an object pointer to a pointer with a less strict alignment
and back again to the original type is promised to work -- but
representation changes are permitted along the way

d) casting a pointer into an integral type might work (implementation
defined) if the type is wide enough, possibly changing representation
as it goes. Casting an integral type to a pointer might work
(implementation defined). In C89, the result of converting a pointer
to an integral type and back need not compare equal to the original;
in K&R2 and C99 it must compare equal if it is defined at all.

e) function pointers are not object pointers and nothing in the
C89 standard requires that they be convertable to any kind of object
pointer, including no requirement at any level that converting them
to void* will work.

f) function pointers may be converted to a different kind of function
pointer and back again and the result must compare equal to the
original

g) outputting a pointer with a %p format and scanning it back in with %p
format will result in something that compares equal to the original
pointer if the implementation makes %p meaningful at all.

Thus, even just casting an object pointer to char* and storing that
is not certain to result in a bitwise storage identical to the
original object pointer -- and if the garbage collector doesn't know
all the representation conversions that -might- take place and try
them all, it can believe a pointer to be unused when it is still in use.
--
All is vanity. -- Ecclesiastes
Oct 16 '06 #85
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <45**********************@news.orange.fr>,
jacob navia <ja***@jacob.remcomp.frwrote:
>>Note that if the APIs are part of some DLLs the GC will see them anyway.

That statement is vacuously true, since if the number of DLLs that the
GC would pay attention to is precisely zero, that would still be
"some DLLs".

Are you talking about some -particular- DLLs? Are you saying that
the particular GC library you mentioned is able to locate pointers
properly throughout -all- DLLs? Throughout all DLLs specially compiled
with the library??

Your original posting mentioned a number of operating systems, most
of which don't have *any* DLLs. For example, the IRIX operating system
mentioned does not have DLLs (it has DSOs, Dynamic Shared Objects,
but those don't appear to have the same connotations; Windows uses
lots of DLLs, but DSOs are not used particularily often with IRIX,
at least not "Dynamic"-ally.)
I don't know in any detail how DLLs work, so the following is largely
guesswork on my part.

<GUESS>
DLLs provide a way to share executable code between two or more
simultaneously executing processes. But any *data* that's associated
with some process must be stored in the process's own address space,
not in some space associated with the DLL. (Otherwise processes could
step on each other's data, which would be A Bad Thing.)
</GUESS>
>>Casts to integers do not affect the GC at all.

Amazing. How does the GC deal with the fact that on a number of
systems, pointers are 64 bits, but 'int' is only 32 bits ?
Conversions from 64-bit pointers to 32-bit integers obviously aren't
going to work, regardless of GC. But jacob said "integers"; he didn't
mention the specific type "int". GC shouldn't be affected by
conversions from, say, void* to uintptr_t; the GC code isn't going to
care whether something that looks like an address is stored in an
object of type void*, in an object of type uintptr_t, or (presumably)
in a register used to hold an intermediate result not associated with
any declared object.
And how does it deal with representation changes that can occur
when casting pointers? About all the C89 standard promises is that
[snip]
>
Thus, even just casting an object pointer to char* and storing that
is not certain to result in a bitwise storage identical to the
original object pointer -- and if the garbage collector doesn't know
all the representation conversions that -might- take place and try
them all, it can believe a pointer to be unused when it is still in use.
It's already been established that at least one GC implementation is
not 100% portable; I think jacob said that Boehm GC works only on
Windows and Linux-like systems. My guess is that it works only on
systems where conversions between pointers and integers, or between
pointers and pointers, do not change the representation. (I'm sure it
could be adapted to work on systems where such conversions do cause a
change of representation, but I don't know of any such systems in real
life.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 16 '06 #86
Keith Thompson wrote:
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
>>In article <45**********************@news.orange.fr>,
jacob navia <ja***@jacob.remcomp.frwrote:
>>>Note that if the APIs are part of some DLLs the GC will see them anyway.

That statement is vacuously true, since if the number of DLLs that the
GC would pay attention to is precisely zero, that would still be
"some DLLs".

Are you talking about some -particular- DLLs? Are you saying that
the particular GC library you mentioned is able to locate pointers
properly throughout -all- DLLs? Throughout all DLLs specially compiled
with the library??

Your original posting mentioned a number of operating systems, most
of which don't have *any* DLLs. For example, the IRIX operating system
mentioned does not have DLLs (it has DSOs, Dynamic Shared Objects,
but those don't appear to have the same connotations; Windows uses
lots of DLLs, but DSOs are not used particularily often with IRIX,
at least not "Dynamic"-ally.)


I don't know in any detail how DLLs work, so the following is largely
guesswork on my part.

<GUESS>
DLLs provide a way to share executable code between two or more
simultaneously executing processes. But any *data* that's associated
with some process must be stored in the process's own address space,
not in some space associated with the DLL. (Otherwise processes could
step on each other's data, which would be A Bad Thing.)
</GUESS>
>>>Casts to integers do not affect the GC at all.

Amazing. How does the GC deal with the fact that on a number of
systems, pointers are 64 bits, but 'int' is only 32 bits ?


Conversions from 64-bit pointers to 32-bit integers obviously aren't
going to work, regardless of GC. But jacob said "integers"; he didn't
mention the specific type "int". GC shouldn't be affected by
conversions from, say, void* to uintptr_t; the GC code isn't going to
care whether something that looks like an address is stored in an
object of type void*, in an object of type uintptr_t, or (presumably)
in a register used to hold an intermediate result not associated with
any declared object.

>>And how does it deal with representation changes that can occur
when casting pointers? About all the C89 standard promises is that

[snip]
>>Thus, even just casting an object pointer to char* and storing that
is not certain to result in a bitwise storage identical to the
original object pointer -- and if the garbage collector doesn't know
all the representation conversions that -might- take place and try
them all, it can believe a pointer to be unused when it is still in use.


It's already been established that at least one GC implementation is
not 100% portable; I think jacob said that Boehm GC works only on
Windows and Linux-like systems. My guess is that it works only on
systems where conversions between pointers and integers, or between
pointers and pointers, do not change the representation. (I'm sure it
could be adapted to work on systems where such conversions do cause a
change of representation, but I don't know of any such systems in real
life.)
I agree with this.
1) Obviously if you truncate (through a cast or otherwise) a pointer,
its value is gone, and the GC can't do anything about it...
2) When a cast changes the representation the same as (1) applies
3) Boehm's GC is portable in Unix and under windows. This is a big
portion of the total "market" but it is not everything. Anyway
nobody is saying that is portable to all C systems.

jacob
Oct 16 '06 #87
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
I agree with this.
1) Obviously if you truncate (through a cast or otherwise) a pointer,
its value is gone, and the GC can't do anything about it...
2) When a cast changes the representation the same as (1) applies
3) Boehm's GC is portable in Unix and under windows. This is a big
portion of the total "market" but it is not everything. Anyway
nobody is saying that is portable to all C systems.
Which is why it's largely off-topic in comp.lang.c.

Much of this discussion, which has been of the form:

Q: Can GC be implemented in 100% portable C?
A: No, and here's why.

has been topical. Advocating GC as a universal solution is not.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Oct 16 '06 #88
jacob navia wrote:
Bart wrote:
A lot of things in Windows are done by passing pointers to APIs (even
casting them to integers sometimes) and getting them back later through
callbacks. Obviously, the program doesn't hold those pointers in the
mean time. For such uses this GC is quite limiting.

Note that if the APIs are part of some DLLs the GC will see them anyway.
Casts to integers do not affect the GC at all.
But I don't have any guarantees about what those DLLs do with my
pointers. I'd rather deal with memory leaks than with GC-related bugs
in some DLL I didn't write and for which I don't have any source code.

Besides there's more to resource management than malloc/free. Open
files, handles, connections, matched calls to some APIs. Those all have
the same inherent problems that memory allocation has. So why a GC
specifically to deal with just one problem? I suspect that, for C
programmers who would want something like this, just writing a few C++
wrappers that do some magic in constructors/destructors would probably
be a lot less painful than your GC.

Regards,
Bart.

Oct 16 '06 #89
"Bart" <ba***********@gmail.comwrites:
Besides there's more to resource management than malloc/free. Open
files, handles, connections, matched calls to some APIs. Those all have
the same inherent problems that memory allocation has.
These can usually be handled nicely through a "pool allocator"
interface.
So why a GC
specifically to deal with just one problem? I suspect that, for C
programmers who would want something like this, just writing a few C++
wrappers that do some magic in constructors/destructors would probably
be a lot less painful than your GC.
I think that moving C programs to C++ is likely to be more
painful than, well, almost any other solution.
--
"This is a wonderful answer.
It's off-topic, it's incorrect, and it doesn't answer the question."
--Richard Heathfield
Oct 16 '06 #90
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) wrote:
# In article <45**********************@news.orange.fr>,
# jacob navia <ja***@jacob.remcomp.frwrote:
#
# >Note that if the APIs are part of some DLLs the GC will see them anyway.
#
# That statement is vacuously true, since if the number of DLLs that the
# GC would pay attention to is precisely zero, that would still be
# "some DLLs".

The program must have live pointers in its address space, or
somehow attached to it. For example write the pointer to disk
and erase the in-memory copy will lose the block. If windows
hides pointers outside the address space, you lose.

# >Casts to integers do not affect the GC at all.
#
# Amazing. How does the GC deal with the fact that on a number of
# systems, pointers are 64 bits, but 'int' is only 32 bits ?

It looks for byte strings subject to certain conditions that
look like heap addresses. If you change a pointer so that it
is no longer recognisable, you lose.

# And how does it deal with representation changes that can occur
# when casting pointers? About all the C89 standard promises is that

If the string of bytes making up the address value remain
recognisable, it can sweep and mark. If not, you lose.

Boehm-Demers segregates blocks to pages by block size. From a
pointer you get the page addres; from the page, the block size;
then the block first byte address. Interior block pointers do
not cause problems. Converting the addresses to something
unrecognisable causes problems.

# e) function pointers are not object pointers and nothing in the
# C89 standard requires that they be convertable to any kind of object
# pointer, including no requirement at any level that converting them
# to void* will work.

Code, own variables, heap, and stack are different parts of the
address space. Most operating systems give you some kind of map
from page addresses to memory area.

# All is vanity. -- Ecclesiastes

We are all bytes in the wind.

Boehm-Demers garbage collection doesn't work for all programs on
all systems. The systems it has been ported to do work (ie they
have been verified with system libraries and compilers) if you
write your programs in the restricted language.

Personally I'm not interested in exotic and/or program-me-if-you-dare
systems. And I do not find the rules difficult to follow.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
I ASSURE YOU WE'RE OPEN!
Oct 17 '06 #91
"Bart" <ba***********@gmail.comwrote:

# Besides there's more to resource management than malloc/free. Open
# files, handles, connections, matched calls to some APIs. Those all have
# the same inherent problems that memory allocation has. So why a GC
# specifically to deal with just one problem? I suspect that, for C

Some collectors support an operation called finalisation. You can
attach a procedure to a block which is called when the block becomes
garbage. For example, you can attach a file closer to a file object.

# programmers who would want something like this, just writing a few C++
# wrappers that do some magic in constructors/destructors would probably
# be a lot less painful than your GC.

Shows how twisted things have become. OO became big with Smalltalk
that include garbage collection. C++ didn't have garbage collection
and it was soon discoverred that OO programs generated a lot of
heap memory and freeing those was a major pain. So destructors were
invented to move all this freeing into the object class instead of
the code using the object. This created a new problem in ensuring
the destructor was called at the appropriate time; this gets hard
with throw chains, gotos, long jumps, etc. All this complication was
added because garbage collection was unavailable.

Garbage collection + finalisation allows you everything destructors
do with fewer restrictions in the language and less work by
programmers.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
JUSTICE!
Justice is dead.
Oct 17 '06 #92
SM Ryan wrote:
"Bart" <ba***********@gmail.comwrote:

# Besides there's more to resource management than malloc/free. Open
# files, handles, connections, matched calls to some APIs. Those all have
# the same inherent problems that memory allocation has. So why a GC
# specifically to deal with just one problem? I suspect that, for C

Some collectors support an operation called finalisation. You can
attach a procedure to a block which is called when the block becomes
garbage. For example, you can attach a file closer to a file object.

# programmers who would want something like this, just writing a few C++
# wrappers that do some magic in constructors/destructors would probably
# be a lot less painful than your GC.

Shows how twisted things have become. OO became big with Smalltalk
that include garbage collection. C++ didn't have garbage collection
and it was soon discoverred that OO programs generated a lot of
heap memory and freeing those was a major pain. So destructors were
invented to move all this freeing into the object class instead of
the code using the object. This created a new problem in ensuring
the destructor was called at the appropriate time; this gets hard
with throw chains, gotos, long jumps, etc. All this complication was
added because garbage collection was unavailable.

Garbage collection + finalisation allows you everything destructors
do with fewer restrictions in the language and less work by
programmers.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
JUSTICE!
Justice is dead.
EXACTLY.

It is amazing how deep the implications of this go. For instance, it
has been argued that you need constructors/destructors to support
operator overloading in C, since operator overloading needs to destroy
intermediate objects in expressions:
c = (a+b)/(a-b);
when '+' is overloaded, it must create a temporary object. This is
possible using the GC, since you are sure the GC will find the
unneeded object.

An enormous system of tables (DWARF3 tables) has been developed to
handle the throw/catch problem of C++. When you make a throw, the
destructors must be called to free the memory. All this is again
unnecessary using the GC. You can use longjmp/throw/catch without any
fear of making amemory leak.

Note that DWARF3 tables can make 10% or more of the code size in C++
applications)

Passing buffers from one thread to another is much easier with the GC.
You do not need to care when your buffer is going to be reclaimed.
There is no need to synchronize threads and wait for them to use the
buffer. You can send the allocated buffer and forget about it, the GC
will reclaim it anyway.

ETC ETC ETC.

The GC simplifies complex programs in a BIG way. It makes many features
of C++ unnecessary. C is a different thing with the GC.

jacob
Oct 17 '06 #93
jacob navia <ja***@jacob.remcomp.frwrites:
SM Ryan wrote:
>"Bart" <ba***********@gmail.comwrote:
# Besides there's more to resource management than malloc/free. Open
# files, handles, connections, matched calls to some APIs. Those all have
# the same inherent problems that memory allocation has. So why a GC
# specifically to deal with just one problem? I suspect that, for C
Some collectors support an operation called finalisation. You can
attach a procedure to a block which is called when the block becomes
garbage. For example, you can attach a file closer to a file object.
# programmers who would want something like this, just writing a few
C++
# wrappers that do some magic in constructors/destructors would probably
# be a lot less painful than your GC.
Shows how twisted things have become. OO became big with Smalltalk
that include garbage collection. C++ didn't have garbage collection
and it was soon discoverred that OO programs generated a lot of
heap memory and freeing those was a major pain. So destructors were
invented to move all this freeing into the object class instead of
the code using the object. This created a new problem in ensuring
the destructor was called at the appropriate time; this gets hard
with throw chains, gotos, long jumps, etc. All this complication was
added because garbage collection was unavailable.
Garbage collection + finalisation allows you everything destructors
do with fewer restrictions in the language and less work by
programmers.
--
SM Ryan http://www.rawbw.com/~wyrmwif/
JUSTICE!
Justice is dead.

EXACTLY.

It is amazing how deep the implications of this go. For instance, it
has been argued that you need constructors/destructors to support
operator overloading in C, since operator overloading needs to destroy
intermediate objects in expressions:
c = (a+b)/(a-b);
when '+' is overloaded, it must create a temporary object. This is
possible using the GC, since you are sure the GC will find the
unneeded object.
Garbage Collection is the invention of the Devil.

It encourages lax design & programming styles.

I hated it in java and I would hate it in C/C++.

We made do with centralised pool allocation/deallocation libraries and
careful matching of alloc/dealloc for years.

Being sreful whenver malloc was called also meant there was some
consideration for when to do it - we tended to be more tight with our
memory uses.

It suddenly seems very popular to assume anything using malloc is as
leaky as a sieve - it is simply not so.

C is C. Lets keep it that way. A real mans language .....
Oct 17 '06 #94
Richard wrote:
jacob navia <ja***@jacob.remcomp.frwrites:

>>SM Ryan wrote:
>>>"Bart" <ba***********@gmail.comwrote:
# Besides there's more to resource management than malloc/free. Open
# files, handles, connections, matched calls to some APIs. Those all have
# the same inherent problems that memory allocation has. So why a GC
# specifically to deal with just one problem? I suspect that, for C
Some collectors support an operation called finalisation. You can
attach a procedure to a block which is called when the block becomes
garbage. For example, you can attach a file closer to a file object.
# programmers who would want something like this, just writing a few
C++
# wrappers that do some magic in constructors/destructors would probably
# be a lot less painful than your GC.
Shows how twisted things have become. OO became big with Smalltalk
that include garbage collection. C++ didn't have garbage collection
and it was soon discoverred that OO programs generated a lot of
heap memory and freeing those was a major pain. So destructors were
invented to move all this freeing into the object class instead of
the code using the object. This created a new problem in ensuring
the destructor was called at the appropriate time; this gets hard
with throw chains, gotos, long jumps, etc. All this complication was
added because garbage collection was unavailable.
Garbage collection + finalisation allows you everything destructors
do with fewer restrictions in the language and less work by
programmers.
--
SM Ryan http://www.rawbw.com/~wyrmwif/
JUSTICE!
Justice is dead.

EXACTLY.

It is amazing how deep the implications of this go. For instance, it
has been argued that you need constructors/destructors to support
operator overloading in C, since operator overloading needs to destroy
intermediate objects in expressions:
c = (a+b)/(a-b);
when '+' is overloaded, it must create a temporary object. This is
possible using the GC, since you are sure the GC will find the
unneeded object.


Garbage Collection is the invention of the Devil.

It encourages lax design & programming styles.

I hated it in java and I would hate it in C/C++.

We made do with centralised pool allocation/deallocation libraries and
careful matching of alloc/dealloc for years.
Maybe you enlighten us?

It is the second time you mention this "pool libraries" for ressource
management.

What do you mean exactly?

How does the algorithm looks like?

Thanks

jacob
Oct 17 '06 #95
jacob navia <ja***@jacob.remcomp.frwrites:
Richard wrote:
>jacob navia <ja***@jacob.remcomp.frwrites:
>>>SM Ryan wrote:

"Bart" <ba***********@gmail.comwrote:
# Besides there's more to resource management than malloc/free. Open
# files, handles, connections, matched calls to some APIs. Those all have
# the same inherent problems that memory allocation has. So why a GC
# specifically to deal with just one problem? I suspect that, for C
Some collectors support an operation called finalisation. You can
attach a procedure to a block which is called when the block becomes
garbage. For example, you can attach a file closer to a file object.
# programmers who would want something like this, just writing a few
C++
# wrappers that do some magic in constructors/destructors would probably
# be a lot less painful than your GC.
Shows how twisted things have become. OO became big with Smalltalk
that include garbage collection. C++ didn't have garbage collection
and it was soon discoverred that OO programs generated a lot of
heap memory and freeing those was a major pain. So destructors were
invented to move all this freeing into the object class instead of
the code using the object. This created a new problem in ensuring
the destructor was called at the appropriate time; this gets hard
with throw chains, gotos, long jumps, etc. All this complication was
added because garbage collection was unavailable.
Garbage collection + finalisation allows you everything destructors
do with fewer restrictions in the language and less work by
programmers.
--
SM Ryan http://www.rawbw.com/~wyrmwif/
JUSTICE!
Justice is dead.

EXACTLY.

It is amazing how deep the implications of this go. For instance, it
has been argued that you need constructors/destructors to support
operator overloading in C, since operator overloading needs to destroy
intermediate objects in expressions:
c = (a+b)/(a-b);
when '+' is overloaded, it must create a temporary object. This is
possible using the GC, since you are sure the GC will find the
unneeded object.
Garbage Collection is the invention of the Devil.
It encourages lax design & programming styles.
I hated it in java and I would hate it in C/C++.
We made do with centralised pool allocation/deallocation libraries
and
careful matching of alloc/dealloc for years.

Maybe you enlighten us?

It is the second time you mention this "pool libraries" for ressource
management.
I did? First time I thought, anyway. However you want them to look.

There are laws : if you call them to allocate, you call them to
deallocate. The difference being that during program development you can
log/track accesses and discover the dangling pointers relatively
quickly : one of the main reasons for any level for abstraction. if your
system maintains a pool of runtime objects, allocate them from a
centralised, controlled pool.

Dont get me wrong : its not "very" easy. But then neither is good C programming
or good "any" programming for that

Nothing magic.
Oct 17 '06 #96

"SM Ryan" <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrote in
message news:12*************@corp.supernews.com...
Garbage collection + finalisation allows you everything destructors
do with fewer restrictions in the language and less work by
programmers.
everything? so this garbage collection doesn't use any more memory than hand
written malloc/free code, and the application doesn't run slower than hand
written malloc/free code, and there are no relatively long (compared to
free()) pauses while garbage collection goes on?
wow that's phantastic and incredible.
Oct 20 '06 #97
"Paul Connolly" <pg********@blueyonder.co.ukwrote:
#
# "SM Ryan" <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrote in
# message news:12*************@corp.supernews.com...
#
# Garbage collection + finalisation allows you everything destructors
# do with fewer restrictions in the language and less work by
# programmers.
#
# everything? so this garbage collection doesn't use any more memory than hand

Then don't use it.

This involves a technical point of language design. Destructors
were added to C++ because it had no garbage collection. The
result is far more complicated language implementation which
can still has implicit storage management activated.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
No pleasure, no rapture, no exquisite sin greater than central air.
Oct 20 '06 #98
Paul Connolly wrote:
"SM Ryan" <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrote in
message news:12*************@corp.supernews.com...

>>Garbage collection + finalisation allows you everything destructors
do with fewer restrictions in the language and less work by
programmers.


everything? so this garbage collection doesn't use any more memory than hand
written malloc/free code,
Not really. Garbage is automatically collected. You can fine-tune this,
specifying the threshold or call a gc when you think it is a good moment
to do that.
and the application doesn't run slower than hand
written malloc/free code,
No, it doesn't run slower. Allocation is a bit slower since each
allocation does a bit of a GC (incremental GC)
and there are no relatively long (compared to
free()) pauses while garbage collection goes on?
There are pauses, but in modern workstations this is barely noticeable.
wow that's phantastic and incredible.
Write in assembly. That's a *real* language :-)
Oct 20 '06 #99
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrites:
"Paul Connolly" <pg********@blueyonder.co.ukwrote:
#
# "SM Ryan" <wy*****@tango-sierra-oscar-foxtrot-tango.fake.orgwrote in
# message news:12*************@corp.supernews.com...
#
# Garbage collection + finalisation allows you everything destructors
# do with fewer restrictions in the language and less work by
# programmers.
#
# everything? so this garbage collection doesn't use any more memory than hand

Then don't use it.

This involves a technical point of language design. Destructors
were added to C++ because it had no garbage collection. The
result is far more complicated language implementation which
can still has implicit storage management activated.
Destructors do more than releasing memory. And finalisation is not a
good substitute for these tasks as finalisation is not synchronous.

Yours,

--
Jean-Marc
Oct 20 '06 #100

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Ganesh | last post: by
11 posts views Thread by Rick | last post: by
34 posts views Thread by Ville Voipio | last post: by
5 posts views Thread by Bob lazarchik | last post: by
8 posts views Thread by mike2036 | last post: by
28 posts views Thread by Goalie_Ca | last post: by
56 posts views Thread by Johnny E. Jensen | last post: by
350 posts views Thread by Lloyd Bonafide | last post: by
158 posts views Thread by pushpakulkar | last post: by
reply views Thread by kmladenovski | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.