Re: Ranting about JVM's default memory limits...
On Mon, 4 Aug 2008, Peter Duniho wrote:
On Mon, 04 Aug 2008 04:02:01 -0700, Tom Anderson <twic@urchin.earth.li>
wrote:
[...]
.NET doesn't collect by moving a pointer. It allocates memory by moving a
pointer, and it moves objects from one generation to another by moving a
pointer.
Okay. Does a compaction occur before the moving from one generation?
As far as I know, yes. (Note that this is a change from what I stated
previously...I've had a chance to re-read the materials I'd been basing
my recollection on before, and while it's possible there's some detail
that was left out from the reference, and while not compacting the
newest generation would in fact be a viable strategy, I think .NET does
compact before adjusting the generation pointers.
I would be absolutely stunned if it didn't.
It's just that it does compaction in-place, which has some potential
performance implications).
Yes, quite possibly.
If not, how is garbage-filled space reclaimed?
If so, what advantage does this have over copying the objects into the
older generation's space? I guess it means that the older generation
doesn't fill up, it just grows, meaning you aren't forced to do a
collection on that generation at any point. Aha. Is that the whole point?
Basically, yes. .NET has three generations (not two as I said before),
and it mostly ignores older generations until it really has to deal with
them. So those generations can become fragmented by unused objects for
some extended period of time. But .NET doesn't worry about them most of
the time, so it doesn't cost anything in performance, until generations
change.
Absolutely, that's standard for generational collectors. You assume that
there isn't *that* much garbage in the older generations, so you don't
bother collecting them all that frequently.
If Java is copying references from one generation storage to another,
then it incurs a compaction cost whether compaction is really necessary
or not. In .NET, if you've got a large stretch objects at the
generational boundary that are only aging, they can be moved from one
generation to the other without any more effort than just moving the
pointer.
Right. AIUI, what you're saying is that if you have a situation like this
(letters are live objects, dots are garbage):
|
ABCDEFGHIJKLMNOPQRSTUV|wxyzab...c..de.f.g...hi
old generation | nursery
You can just bump the boundary:
|
ABCDEFGHIJKLMNOPQRSTUVwxyzab|...c..de.f.g...hi
old generation | nursery
Well, and then compact the rest, and bump again:
|
ABCDEFGHIJKLMNOPQRSTUVwxyzabcdefghi|..........
old generation | nursery
Yes, if that does happen, you can avoid copying a bunch of objects.
But, if the generation you're ageing is the nursery, i don't think that
will ever happen. Remember, the vast majority of objects die in the
nursery. The chances of getting a substantial run of live objects, or even
a region of reasonably dense liveness, are astronomically small. The
normal situation looks more like this:
|
ABCDEFGHIJKLMNOPQRSTUV|...w..x.....y..z....a.....bc
old generation | nursery
The only sane thing to do is to compact the nursery.:
|
ABCDEFGHIJKLMNOPQRSTUVwxyzabc|.....................
old generation | nursery
This is how a 'normal' generational collector does it - before:
|
ABCDEFGHIJKLMNOPQRSTUV..........|...w..x.....y..z....a.....bc
old generation | nursery
And after:
|
ABCDEFGHIJKLMNOPQRSTUVwxyzabc...|............................
old generation | nursery
How often this comes up, I don't know. It really depends on the
allocation patterns of the application. But recommended practice is to
allocate long-lived objects early on, and then only allocate short-lived
objects, and following that recommendation a .NET application could in
fact find itself having very little work to do with respect to
compacting the heap.
The first time it runs GC, perhaps. But later on, the nursery will be
mostly full of short-lived objects.
MSDN has detailed references regarding the design of the .NET GC system. I
don't have the links handy, but if the above clarification doesn't address
your concerns, I'm happy to search for them and post them here.
You're very kind. I think i may be understanding what you mean now, though,
so no need!
I apologize for distracting this thread with .NET cruft. I brought it
up mainly as a way of contrasting how different GC strategies might
work, and what implications that might have for how memory constraints
might affect Java. But I acknowledge that it took us off to an
off-topic tangent.
I don't think you have anything to apologize for. Discussion of
alternative approaches to GC is entirely on-topic.
tom
--
Imagine a city where graffiti wasn't illegal, a city where everybody
could draw wherever they liked. Where every street was awash with a
million colours and little phrases. Where standing at a bus stop was never
boring. A city that felt like a living breathing thing which belonged to
everybody, not just the estate agents and barons of big business. Imagine
a city like that and stop leaning against the wall - it's wet. -- Banksy