User: Password:
|
|
Subscribe / Log in / New account

Pauses

Pauses

Posted Jun 17, 2010 14:01 UTC (Thu) by nix (subscriber, #2304)
In reply to: Pauses by ncm
Parent article: The Managed Runtime Initiative

(the following is teaching my grandfather to suck eggs)

Part of the problem is that writing a GC that tracks stuff residing on the C stack requires either pervasive changes to how your program does *all* its memory management, or (for things like the Chicken collector) pervasive changes to how your functions call each other and how the stack is managed. (The Boehm GC, via a triumph of inspired hackery, manages to do the first without source code changes: but it's computationally expensive as GCs go, not type-accurate, and can sometimes leave extra garbage lying around. I don't really understand why more C programs don't use the Boehm GC, though, it's a hell of a lot better than no GC at all. Perhaps C programmers *like* manual memory management? :/ )

If you can guarantee that you'll never have pointers to GCed objects anywhere on the C stack when a GC happens, it gets much much simpler, but this is a really rather harsh requirement and most systems using a GC cannot satisfy it.


(Log in to post comments)

Pauses

Posted Jun 17, 2010 14:18 UTC (Thu) by Tet (subscriber, #5433) [Link]

Perhaps C programmers *like* manual memory management?

Yes, some of us do. Or rather, I don't like doing it in and of itself. But I love the determinism of it.

Pauses

Posted Jun 17, 2010 15:16 UTC (Thu) by nix (subscriber, #2304) [Link]

Quite so. Deterministic GC is possible: it's just GC in which you must explicitly insert calls to fire off a GC cycle. (At the C level, this is how all garbage collectors are implemented, of course...)

But when you're dealing with complex enough data structures (lots of cycles, trees with pointers to each other and so on), explicit memory management moves from 'deterministic' to 'lethally complex and horrifically annoying'. That's when GC really starts to be useful (and that's why GCC has a special-purpose garbage collector of its very own.)

Pauses

Posted Jun 18, 2010 13:47 UTC (Fri) by i3839 (guest, #31386) [Link]

That's when you have to start simplifying and improving your design instead.

Seriously, you have to keep track of all links and pointers and datastructures anyway, memory management is only very little additional work. If it's lethally complex and horrifically annoying then your other code is too.

Pauses

Posted Jun 20, 2010 20:11 UTC (Sun) by nix (subscriber, #2304) [Link]

Unfortunately, some problems (e.g. anything at all to do with translation/compilation/optimization) simply *are* intrinsically complex, and anything involving graphs with entities attached with varying lifetimes *is* going to have a horrific time without GC. (Reference counting can help in many other cases, but if the graphs have any cycles in them, you're dead.)

Pauses

Posted Jun 22, 2010 13:48 UTC (Tue) by i3839 (guest, #31386) [Link]

Yeah, graphs with cycles are tricky to do without GC. You would need to
walk the graph and basically do manual GC now and then. That's a hundred
lines of extra code which runs when you want it to run. Trying to do more
classic manual memory management would be horrific indeed, but when done in
a way that fits the situation it adds negligible coding/complexity overhead.

For complication/translation/optimization stuff you generally can just
allocate everything you need and throw everything away afterwards, e.g.
at program exit. Usually the optimization complexity explodes, so you
want to limit the size of the problem anyway.

It's like with locking; You don't have to always use the same granularity.

Pauses

Posted Jun 22, 2010 20:30 UTC (Tue) by nix (subscriber, #2304) [Link]

For complication/translation/optimization stuff you generally can just allocate everything you need and throw everything away afterwards, e.g. at program exit.
Hang on, I thought people were complaining that GCC used too much memory? This would make its memory use balloon insanely (many gigabytes to compile any nontrivial program).

Compilation always creates many intermediate data structures, many of which are elaborate graphs or have pointers to each other. You really do want to throw them away when you can, and you really do not want to do this by hand.

Pauses

Posted Jun 22, 2010 22:53 UTC (Tue) by i3839 (guest, #31386) [Link]

In my experience most memory is used when linking, not when compiling,
but I guess it can get pretty bad when compiling huge C++ codes with
plenty templates.

The thing is, you probably can't throw away much in each intermediate step,
because you do need all that info, but you can easily throw away data
generated by a whole intermediate step and keep only the intermediate
results. So the main way to limit memory usage is by limiting the working
set. GC doesn't help with that.

Anyway, gcc already uses GC it seems, so if it uses too much memory then
adding a GC won't help. (http://gcc.gnu.org/wiki/Memory_management)
That it would use much more without GC seems unlikely.

I guess my argument boils down to: Managing object lifetime is only a
small part of memory management, and GC only helps with that.

Pauses

Posted Jun 23, 2010 13:10 UTC (Wed) by nix (subscriber, #2304) [Link]

In my experience most memory is used when linking, not when compiling
The only reason you think that is because GCC runs several garbage collections when compiling even a small file.

And your assumption about being able to throw away whole intermediate steps at once -- that's how GCC used to work when it kept everything in obstacks. It's often correct, but if it's wrong only in part you have to keep a lot around because you have no way to tell which bits you're using and which you're not.

(actually, to be maximally pedantic it's almost never correct because most passes annotate or shuffle some tree somewhere: if it did nothing all the time it would be a pretty useless pass.)

But it seems you don't get it. I know GCC already has a GC: I'm using it as a counterexample to your claim that GC is unnecessary because you can always simplify your datastructures. You cannot always do that (although you often can and it should be the first thing you try, if practicable), and doing it by hand (i.e. explicitly triggering GC cycles) is often impractical too.

Managing (or rather mismanaging) object lifetime is the part of memory management that is most likely to cause bugs in C programs (less so in C++); GC largely eliminates that as a cause of bugs.

Pauses

Posted Jun 25, 2010 14:57 UTC (Fri) by i3839 (guest, #31386) [Link]

> (actually, to be maximally pedantic it's almost never correct because
> most passes annotate or shuffle some tree somewhere: if it did nothing
> all the time it would be a pretty useless pass.)

That's why I was talking about compilation stages, not optimisation
stages. I don't think you can free any significant amount of memory
between the latter ones, because you never know what may be needed
in the future. Even if you just replace multiple nodes with fewer ones
you can't save much memory because of fragmentation. At best it's a
factor 2, in which case you have to manage overall memory consumption
by reducing your working set anyway.

I'm also sure that GCC does not use hundreds of megabytes to keep
very complex graphs in memory.

I'd rather have GCC spend its time on using 10 times the memory for
compiling small files fast than waste time on reducing memory usage
by running slower and not really achieving it anyway.

> But it seems you don't get it. I know GCC already has a GC: I'm using it
> as a counterexample to your claim that GC is unnecessary because you can
> always simplify your datastructures. You cannot always do that (although
> you often can and it should be the first thing you try, if practicable),
> and doing it by hand (i.e. explicitly triggering GC cycles) is often
> impractical too.

No, I don't get it. You brought GCC as an example of something that people
complain about that uses too much memory, and of something that uses
complex datastructures that can't be easily handled with manual memory
handling. What I'm trying to say is that GC doesn't solve any real problems,
it's just convenience for the lazy, but when you do use too much memory
(bloat or leak) it won't help you at all. When memory handling is important
then you have to put it into your program design on a higher level. You seem
to assume that GCC would use a lot more memory if it didn't use GC. I think
it's rather that GC doesn't improve the situation.

> Managing (or rather mismanaging) object lifetime is the part of memory
> management that is most likely to cause bugs in C programs (less so in
> C++); GC largely eliminates that as a cause of bugs.

In my experience memory leaks almost never happen and when they do
happen they're easily fixed. At least in C: When it happens with Java it's
a bit harder because then you have to hunt down the dangling references
and you can't use Valgrind. Firefox is a different story, but even a perfect
GC wouldn't have saved it. (But the problem of C++ programs is that C++
adds its own additional complexity without making anything easier, with
as a result more bugs and memory leaks in general.)

Pauses

Posted Jun 27, 2010 17:05 UTC (Sun) by nix (subscriber, #2304) [Link]

That's why I was talking about compilation stages, not optimisation stages.
There is no meaningful distinction, after parsing, between translation and optimization. There are only compilers that optimize more, and compilers that optimize less.
I'm also sure that GCC does not use hundreds of megabytes to keep very complex graphs in memory.
You're hilariously wrong. (Seriously, what do you think it's doing with the gigabytes of space it can sometimes use? Playing electronic tic-tac-toe? Of course it's holding graphs, and other things some of which it indeed can never throw away e.g. hordes of decl nodes for all the declarations in all the header files it's parsed...)
I'd rather have GCC spend its time on using 10 times the memory for compiling small files fast than waste time on reducing memory usage by running slower and not really achieving it anyway.
You'd say that until you tried to compile something and it failed because you ran out of memory, or it started taking a thousand times longer than otherwise because you were pushed into swap. Also, the more we reduce memory usage, the better our (still quite awful) cache utilization becomes.
You seem to assume that GCC would use a lot more memory if it didn't use GC. I think it's rather that GC doesn't improve the situation.
No. If it never garbage collected and didn't free(), as you suggested, it would use incredibly much more memory (many times more than it does now).

As for what would happen if it was designed without GC, well, we have actual evidence of that because pre-3.0 it did indeed have no GC, and used manual memory management for everything, with explicit lifetimes. Maintaining the object lifetimes was a nightmare and there were countless bugs raised due to SEGVs caused by something being freed when it shouldn't.

In my experience memory leaks almost never happen and when they do happen they're easily fixed.
That's true until you have to manage complex data structures. It's also only true if your memory leak (or, worse, double-free) isn't tied up with an API bug somewhere and not fixable without changing the API. I've seen that too and it was a nightmare to fix (we had to change every caller and there were hundreds, ick, never again).

GC may be more inefficient than manual memory management (theoretically this is not true, but I've never heard of a situation where that theory is turned to practice) and is surely not right for every situation, but it wipes out all these problems at a stroke.

And to be honest if asked if I'd rather have a program that ran more slowly but used GC or a program that didn't work I'd surely pick the former.

Pauses

Posted Jul 4, 2010 17:14 UTC (Sun) by i3839 (guest, #31386) [Link]

Yes, but compilers don't grab the whole source and optimise everything at
once, at least not generally, though they can do that. So it's fine if they
use a bit more memory when compiling one unit, the only moment when the
whole program has to be in memory is when linking.

Considering that optimising is a computationally expensive process which
grows much more than O(n) if the working set increases by n, I'm really
surprised that memory usage is a limiting factor at all, and that compile
time hasn't gone through the roof before this became a problem.

What the hell is gcc doing to achieve this? Making hundreds of copies of
all the nodes every time it modifies them? (I know you can trade memory
usage for time with certain algorithms, but is gcc actually doing that?)

In a dark past I compiled the whole system on a slow, crappy computer with
128 MB of RAM (bloody Gentoo, but Archlinux had no i586 binaries), and I'm
pretty sure it was totally limited by CPU speed. Took a whole day, but it
got to the end. What code makes gcc use hundreds of megabytes of memory
in your experience?

But yeah, if you have a huge body of code with crappy internal APIs then
GC is probably a very good idea. Using explicit memory allocation for short
lived objects plainly sucks, GC is better for that. In normal C the thing is
to avoid such objects in the first place. I only use malloc for long-lived
objects and mostly at program start-up or once per major event, like a new
client connecting. If for whatever reason (IMHO mostly because of bad design,
but not always) the code isn't orderly and clear, but messy, then having
no GC would be a bit of a hell, I admit. But you might want to consider
rewriting the whole thing in Python too, because just using a GC won't
help much. And that's my main point you seem to ignore, that if having GC
improves the situation, it generally means you got other, bigger, design
problems. The case where it's really because of "complex data structures"
is a rare case indeed. Mostly it's unnecessarily complex and then it's
plain bad design.

Pauses

Posted Jul 7, 2010 15:56 UTC (Wed) by nix (subscriber, #2304) [Link]

Yes, but compilers don't grab the whole source and optimise everything at once, at least not generally, though they can do that. So it's fine if they use a bit more memory when compiling one unit, the only moment when the whole program has to be in memory is when linking.
Well, -flto does exactly that. In any case, grabbing one translation unit and optimizing it can easily use hundreds of megabytes of memory, and without doing garbage collections (i.e. never freeing storage) would easily use many gigabytes.
Considering that optimising is a computationally expensive process which grows much more than O(n) if the working set increases by n, I'm really surprised that memory usage is a limiting factor at all, and that compile time hasn't gone through the roof before this became a problem.
Well, compile time having gone through the roof is a perennial complaint about GCC, and its L2 cache utilization is pretty awful.
What the hell is gcc doing to achieve this? Making hundreds of copies of all the nodes every time it modifies them? (I know you can trade memory usage for time with certain algorithms, but is gcc actually doing that?)
No, but it has a lot of optimization passes, several IRs, and it does a lot of work. Also, headers are large these days: decl nodes alone can use hundreds of megabytes, and recent work to reduce the size of decl nodes has reduced the memory consumption of the compiler considerably.

You might find the -fmem-report flag interesting.

(Note that reuse of tree nodes is a classic example of a time where GC is very useful, because all of a sudden that object's lifetime must be extended, and telling the entity that originally allocated it is likely to be unpleasant.)

In a dark past I compiled the whole system on a slow, crappy computer with 128 MB of RAM (bloody Gentoo, but Archlinux had no i586 binaries), and I'm pretty sure it was totally limited by CPU speed. Took a whole day, but it got to the end. What code makes gcc use hundreds of megabytes of memory in your experience?
Virtually anything in C++. Anything more than a few thousand lines long in C. It's downright commonplace. It's pretty common to see GCC using >500Mb, and I've seen it using gigabytes before now. If you run several compilations in parallel, you'll need even more...
But yeah, if you have a huge body of code with crappy internal APIs then GC is probably a very good idea. Using explicit memory allocation for short lived objects plainly sucks, GC is better for that.
That's exactly the class of allocations for which obstacks are good and GC can often be forgone. When you have long-lived allocations in a complex webwork in elaborate interconnected graphs, then is when GC becomes essential. And GCC has elaborate interconnected graphs up the wazoo. The quality of internal APIs is mostly irrelevant here: it's the nature of the data structures that matters.
The case where it's really because of "complex data structures" is a rare case indeed.
I find that about 5% of the programs I write start to get complex enough data structures that memory management becomes a serious burden. I think it depends on the class of program, really. If you mostly write little scripting things or financial add-up-these-numbers programs, then, no, complex data structures will be uncommon. If you're hacking on the inside of a database server or a compiler, then they'll be common.

Pauses

Posted Jul 8, 2010 14:36 UTC (Thu) by etienne (guest, #25256) [Link]

> Note that reuse of tree nodes is a classic example of a time where GC is
> very useful, because all of a sudden that object's lifetime must be
> extended, and telling the entity that originally allocated it is likely
> to be unpleasant.

I am not a specialist of GC, but I wonder if the usual malloc/free interface is wrong, and if we should use something like malloc/memlock/free.
Basically, the function which create the data allocates it, all functions using the data memlock() it, and every function calls free() when it finishes using that data. Free() decrements a counter and frees the memory when the counter reaches zero.
Has that already been tried and what would be the problem of it?

Pauses

Posted Jul 8, 2010 14:52 UTC (Thu) by nye (guest, #51576) [Link]

>Basically, the function which create the data allocates it, all functions using the data memlock() it, and every function calls free() when it finishes using that data. Free() decrements a counter and frees the memory when the counter reaches zero.

How would this be different from any other form of reference counting, with its attendant problems?

Pauses

Posted Jul 9, 2010 16:22 UTC (Fri) by nix (subscriber, #2304) [Link]

Straight reference counting works if you can tell who the 'users' are, and if the data structures are fairly simple. But we can't really ask everyone touching a graph to walk the entire graph and all its data structures and increment, then decrement, all its reference counts (that would be much more cache-unfriendly and unpleasant to maintain than what is done now); and because nodes are often shared between graphs we can't have one giant reference count across the whole graph... and if the reference-count-freer walks the graph and only frees if all connected entities are at refcount zero, you might as well drop the reference count, because what you've got there is a garbage collector. :)

Pauses

Posted Jul 14, 2010 14:23 UTC (Wed) by i3839 (guest, #31386) [Link]

-flto enables link time optimisation, which is IMHO something slightly
different, and earlier (current?) implementation has a reputation of being
slow. I was thinking more about -combine -fwhole-program. As far as I know
link time optimisation is about doing further optimisations before the real
linking.

-fmem-report flag is indeed interesting. On my current project, which
is about 4K lines of C code, it reports 16MB allocated with combine +
whole-program, 12MB when using dietlibc, and max 3MB when compiling
files one at a time.

So assuming C++ is ten times worse, and the code ten times bigger, then
you're indeed easily using gigabytes of memory. I guess you don't want
to compile big C++ programs at once though, doing it per file should be
fine.

> That's exactly the class of allocations for which obstacks are good and
> GC can often be forgone. When you have long-lived allocations in a
> complex webwork in elaborate interconnected graphs, then is when GC
> becomes essential. And GCC has elaborate interconnected graphs up the
> wazoo. The quality of internal APIs is mostly irrelevant here: it's the
> nature of the data structures that matters.

With crappy APIs/design you can't allocate objects on the stack, but are
forced to allocate them dynamically even if they're short lived.

The problem of elaborate interconnected graphs is that it's hard to end
up with nodes with no references at all, so GC usually won't help much.
And even if it does it probably doesn't reduce peak memory usage. So yes,
in such cases you want something like GC, for your own sanity, but it
won't improve the total memory usage much if you don't limit the graph
size some other way.

Pauses

Posted Jul 15, 2010 17:06 UTC (Thu) by nix (subscriber, #2304) [Link]

Link-time optimization works by having the compilation phases drive the compilation to the GIMPLE tree stage, then writing it out and having the link stage invoke the compiler again (via collect2, or via a linker plugin: the latter is preferable because then you can run it over the contents of .a archives as well) to read in all the GIMPLE trees and optimize them. At that stage you've got all the trees written out by all the compilation phases in memory at once. And a good few optimizations will, unless bounded explicitly, start using up crazy amounts of memory when hit with large programs all at once. (Of course they *are* bounded explicitly. At least all of them that anyone noticed are.)

-combine -fwhole-program has a similar memory hit, for similar reasons.

C++ is a good bit worse memory-wise than C, mostly because the headers make C headers look like child's toys: they have a lot of definitions in them and a large number of very complex declarations. I've known compiling *single C++ files* to eat a couple of gigabytes before (although, admittedly, those were exceptional, things like large yacc parsers compiled with C++: mysql's SQL parser is a good example).

Pauses

Posted Sep 6, 2010 20:22 UTC (Mon) by Blaisorblade (guest, #25465) [Link]

> That's why I was talking about compilation stages, not optimisation
stages.
> I don't think you can free any significant amount of memory
between the latter ones, because you never know what may be needed
in the future.

Well, if no pointer exists to an object, there's no way somebody can use it. It seems you don't know what you're talking about.

> Even if you just replace multiple nodes with fewer ones you can't save much memory because of fragmentation

Fragmentation only exists in languages which don't support GC well (i.e., C). GC have been able to fix that for ages. Whether we have decent heuristics for handling it without using too much CPUs is an open issue, when that's a problem choosing the GC algorithm among the implemented ones is the best solution.

Pauses

Posted Sep 6, 2010 20:14 UTC (Mon) by Blaisorblade (guest, #25465) [Link]

> That's when you have to start simplifying and improving your design instead.
> Seriously, you have to keep track of all links and pointers and datastructures anyway, memory management is only very little additional work. If it's lethally complex and horrifically annoying then your other code is too.

First, refcounting is GC, and lots of C programs use it.

I used to program in C in kernel space (on UserModeLinux, I remember a nix, probably you, on our MLs), now I usually program in functional languages. If you ever tried, you'd realize that there, manual memory management would be much more code than getting the job done.

On the other hand, in C, and even in kernel space, reference counting is frequently used, especially for just _everything_ shared among multiple threads. It might be omitted for stuff which is only manipulated under locks in certain ways, but kernel code craves for using as few locks as possible, so refcounting is required by the coding style for such cases.

And reference counting is... just another way to implement GC. Which is probably fine for those usages - but if you implement GC with it, it's often the worst way (because you really use it differently).

Pauses

Posted Sep 6, 2010 21:17 UTC (Mon) by nix (subscriber, #2304) [Link]

Yes, I'm the same Nix :)

The biggest problem with refcounting GC (ignoring the cycle problem) is that its constant tweaking of refcounts leads to appalling cacheline bouncing with concurrent code. (Slightly different from the nasty cache effects of crude old mark-and-sweep collectors.)

Pauses

Posted Sep 6, 2010 22:38 UTC (Mon) by Blaisorblade (guest, #25465) [Link]

The biggest problem with refcounting GC (ignoring the cycle problem) is that its constant tweaking of refcounts leads to appalling cacheline bouncing with concurrent code. (Slightly different from the nasty cache effects of crude old mark-and-sweep collectors.)

Yep, that's what doesn't happen (not that much) in kernel (with explicit refcounting) and what smarter refcounting GCs try to avoid as much as possible. No refcounting for stack operations (which implies a stop-the-world phase to scan the stack) is an old optimization; the Recycler from IBM does something better, but there must be reasons why nobody actually uses it, and reading the paper with attention gives some suggestions. Most importantly, the most reputable comment I got about it was "it's crap", unfortunately I couldn't ask details.

<OT>
Yes, I'm the same Nix :)

Nice to see you again - I've noticed your nick a number of times here. And now I speak as a researcher in programming languages and their implementation - what a huge change.
</OT>

But back to UserModeLinux, I agree that it would definitely make sense to use these tricks, or at least something related (you mentioned that somewhere else). We were actually trying to push forward some code for our needs, i.e. Ingo's remap_file_pages patch, which I resumed. It allowed playing not only with offsets but also with protection bits of individual pages. It seems that here, the guys are doing much more stuff - including, probably, batched VM operations, since they need to use them to set up read barriers, i.e. to trap memory reads for their GC, which was originally developed for a RISC CPU which gives a small HW support for them!

But I would have needed a full-time position to handle that, rather than working on it on my free time, after UML maintenance and support, and UML as a whole was severely lacking manpower. But understanding and fixing some bugs in Ingo Molnar's code (on which he had played just for a small while) was one of my best achievements by that time.

Pauses

Posted Sep 6, 2010 23:17 UTC (Mon) by nix (subscriber, #2304) [Link]

Nice to see you again - I've noticed your nick a number of times here. And now I speak as a researcher in programming languages and their implementation - what a huge change.
I'd wondered what you'd been doing when you dropped out of UML hacking :)

Just like to say thanks for the UML work over the years, it kept my firewall happy for many years before that machine croaked its last and I switched to a Soekris... UML seems to have been obsoleted by qemu now, which is in a way a shame: it did a lot of things in interesting and unusual ways, and I'm fairly sure nobody else had ever abused ptrace() quite as badly (given the number of ptrace() bugs UML teased out, I think we can be sure of it).

allocation in C

Posted Jun 17, 2010 16:02 UTC (Thu) by tialaramex (subscriber, #21167) [Link]

Speaking about the largest C project I work on...

In some places the reason I don't use a GC is because I'm lazy and there wasn't one sat there ready to go. It is possible that I should learn to use the Boehm GC in these cases and that I should evangelise its use.

But in a lot of places it's because it's because the code's on the critical path. I don't see a GC (and particularly one you admit is "computationally expensive") buying us more than it costs in these codepaths. This is optimised code, where people have chosen the algorithms very carefully and read the latest papers, and run benchmarks to find good parameters and done all that good stuff. And we already have (by the nature of the system) an insatiable appetite for RAM so we certainly don't want to make that any worse.

Perhaps a better goal is to stop using C at all for the "lazy" code. I probably spend as little as 30% of my programming time writing C these days anyway, maybe it should be less than 10%. Java for example seems to work well enough, it's slow and it wastes a lot of RAM, and it's missing a bunch of features I like, but it works well enough. Probably a lot of my "lazy" code could be Java, more than already is.

allocation in C

Posted Jun 20, 2010 20:13 UTC (Sun) by nix (subscriber, #2304) [Link]

In some places the reason I don't use a GC is because I'm lazy and there wasn't one sat there ready to go. It is possible that I should learn to use the Boehm GC in these cases and that I should evangelise its use.
Since using the boehm GC in its simplest form consists of including one header and instantly all your malloc()s are garbage-collected, that's not hard. (You don't need to take the free()s out, but they're no longer *necessary*, merely hints that this block no longer needs to be scanned for possible pointers.)

But yes, avoiding C for the boring stuff is probably best. Embed a better language (or embed the C in a better language) and use that, and get GC for free :)

allocation in C

Posted Jun 21, 2010 0:33 UTC (Mon) by khc (guest, #45209) [Link]

Or with LD_PRELOAD ;-) It's hard to decide which one is simpler though.

allocation in C

Posted Jun 21, 2010 20:54 UTC (Mon) by nix (subscriber, #2304) [Link]

I suppose it depends if you have the source to all the bits or not. If you do, using LD_PRELOAD would be just icky. If you don't, it's unavoidable.

Pauses

Posted Jun 17, 2010 17:47 UTC (Thu) by jordanb (guest, #45668) [Link]

> (The Boehm GC, via a triumph of inspired hackery, manages to do the first
> without source code changes: but it's computationally expensive as GCs go,
> not type-accurate, and can sometimes leave extra garbage lying around. I
> don't really understand why more C programs don't use the Boehm GC, though

Seriously?

With a sales pitch like that, who wouldn't use it? :P

Anyway, I think RAII is a better approach to memory management than GC for high-performance applications. It's deterministic and has very little run-time cost. The only disadvantage is that it doesn't exist in C, but it's supported by all modern languages except the ones that have gone the builtin-GC route.

RAII, but no GC?

Posted Jun 17, 2010 19:05 UTC (Thu) by sbishop (guest, #33061) [Link]

I am not aware of a modern language which does not have built-in GC. (Though "built-in GC" is a requirement under most people's definition of "modern language".) Which languages are you thinking of? I don't mean to argue with you; I'm just curious.

I'm also curious to know where RAII is used outside of C++.

RAII, but no GC?

Posted Jun 17, 2010 19:29 UTC (Thu) by alextingle (guest, #20593) [Link]

Python uses RAII, I believe.

RAII, but no GC?

Posted Jun 17, 2010 21:18 UTC (Thu) by tack (guest, #12542) [Link]

Not exactly. It's a peculiarity of (current versions of) CPython that RAII patterns can work, however there's nothing in the language that specifies that behavior, and you can't expect it from other implementations like Jython, or perhaps not even from future versions of CPython.

RAII, but no GC?

Posted Jun 19, 2010 13:39 UTC (Sat) by cortana (subscriber, #24596) [Link]

Perhaps Alex was referring to to the 'with' statement: http://docs.python.org/reference/compound_stmts.html#with

Pauses

Posted Jun 20, 2010 20:18 UTC (Sun) by nix (subscriber, #2304) [Link]

With a sales pitch like that, who wouldn't use it? :P
Heh. Well, it does about as well as it's possible to do in C without massive assistance from the application. But that takes tradeoffs...


Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds