
Azul's Pauseless Garbage Collector - DanielRibeiro
http://www.artima.com/lejava/articles/azul_pauseless_gc.html
======
pdubroy
> Self healing is a unique capability that, as far as we know, the Azul
> collector is the only one to do, and it can only be done with a read
> barrier.

The Metronome GC from IBM Research
([http://www.research.ibm.com/people/d/dfb/papers/Bacon05High....](http://www.research.ibm.com/people/d/dfb/papers/Bacon05High.pdf))
also uses a read-barrier to fix up pointers to objects which have moved.

Although, I don't think it does marking in the read barrier.

------
prodigal_erik
Sounds like fascinating work. I would have expected big unpredictable
performance problems from using a read barrier to lazily fixup references to
moved objects, given how expensive each page fault is in a superscalar
pipeline.

But it's hard to recommend a vendor who's opaque about pricing. If we have to
ask, we probably can't afford it.

~~~
modeless
Page faults are usually expensive because the bits you need must be read in
from disk. In this case the bits you need are still in RAM, and could even
conceivably be in cache. It's probably not tremendously more expensive than a
cache miss (which is still quite expensive, but hopefully the collector is
fixing up pointers fast enough that actual page faults are relatively rare).

~~~
binaryfinery
They'd be about as expensive as throwing an exception. And the live objects
would, I assume, quickly pull all the other live objects into the active
pages. I love this hack.

~~~
danvet
Furthermore they're using 2mb pages instead of the usual 4kb (on x86). That
cuts the overhead by a factor of 512 alone.

The remaining problem I see is cache-trashing because on every minor page-
fault you have to run a part of your mark&sweep algo, surely kicking out all
the application data&code from caches. That's inevitable less efficient than a
stop-the-world approach.

------
stretchwithme
Always taking on the most difficult thing instead of waiting until you have no
choice but to clean house sounds like the best strategy for java garbage
collection, running your life, running a country, you name it.

~~~
Groxx
That doesn't really map to computers, which spend an _enormous_ amount of time
waiting and doing nothing. Putting it off lets you collect when nothing is
happening, which would otherwise be "wasted" time.

More in general, putting things off frequently means being able to handle them
without interruption when the time is right; it's only a problem if the right
time doesn't come up frequently enough (too busy). And context switching is
pretty much guaranteed to be expensive in every circumstance, be it computers,
your life, or a country.

Back to computers again, this would mean that the problem is being too busy,
not that you put it off - they'll likely take about the same amount of time no
matter when they're handled; if anything, they're more likely to be _faster_
if done all at once rather than bit by bit, due to cache behaviors. At that
point you know you have other, larger problems.

~~~
stretchwithme
ok, when all urgent and important things have been attended to, do the most
important, non-urgent thing regardless of how hard it is, until its done or
something urgent and important needs doing.

------
vsingh
Could anyone explain the "self-healing" algorithm in simplistic terms?

From what I gathered, when they compact a page of memory, moving all the
objects within it to different locations, they will set a marker on all
pointers to be "unset". Then, while program execution is still going on, the
GC thread will be busily going through the pointers and correcting them to
their new locations as necessary, then setting the marker flag. If, during
this period, the executing code tries to use an unmarked pointer, a "read
barrier" is hit in the VM, and the GC code corrects that pointer ("self-
heals"), sets the marker, then allows execution to continue.

Do I have this right? What about the initial unsetting of all these markers?
It would seem to require going through all pointers before you want to compact
a page, and I would suspect they're being more clever than that.

~~~
modeless
You don't mark pointers, you unmap a page of virtual memory. This instantly
invalidates all pointers to that page without touching them, and allows you to
immediately reuse that physical memory by mapping it to a new virtual address.
When you eventually dereference a pointer to an unmapped page the processor's
MMU throws a page fault. The VM catches the fault and fixes up the pointer on
the spot.

What I'd like to know is how you can guarantee that all garbage is eventually
collected in a system like this, and how you can guarantee that you've fixed
up all pointers to an unmapped virtual page so you can reuse it.

~~~
bnoordhuis
> how you can guarantee that you've fixed up all pointers to an unmapped
> virtual page so you can reuse it.

Maybe they don't.

amd64 effectively has a 48-bit addressing limit. You can unmap 1,000 4K pages
each second for over two years before you need to reuse a page address.

~~~
modeless
An interesting idea, but I'd imagine the tables you need to maintain to fixup
pointers would become prohibitively large before you ran out of address space.

~~~
bnoordhuis
Perhaps the VM doesn't use tables but a pointer remapping algorithm, something
along the lines of (page_address * large_prime_number) mod 2^48.

~~~
modeless
The problem is you're not just moving whole pages, you're moving and
compacting the objects within that page. Each object in the page has a new
offset in the new page (or pages).

------
icefox
<quote> Can you explain how Azul's pauseless garbage collector works?

Gil Tene: At Azul, we've been building high performance Java virtual machines
(JVM)s for the past eight years now. We started the company in 2002, and we
aimed to solve several scalability and infrastructure problems for Java back
then.... </quote>

Anyone else really hate then people don't actually answer the question? They
should have edited that useless part out.

~~~
paul
The whole rest of the article is him explaining how it works!

~~~
JoachimSchipper
Additionally, "we started a company to make Java faster and garbage collection
was around #3 on our list" _is_ informative. There's only one sentence that
could really be cut ("founded in 2005" or somesuch.)

------
wingo
Wwwwow. The Boehm-Demers-Weiser GC can't move objects because, you know, C is
gnarly and you can't really trust anything to update pointers in-place. But
what if you could? This work seems to indicate that you could have a
compacting collector with arbitrary C programs, given the extra hooks they
added to Linux (<http://lwn.net/Articles/392307/>).

Azul continues to impress.

------
kisiel
The guy says his company solved some difficult engineering problems, but this
is not language of an engineer. "On Zing they generally tend to be below a
millisecond." - what on earth does it mean? He tested it? How? What are the
results? What is the confidence interval?

------
jganetsk
What happens with objects that can't fit on a single page, such as a large
array?

~~~
bensummers
The obvious answer is to use more than one page. Why wouldn't that work with a
special case for "large allocations", like most heap implementations?

~~~
jganetsk
Good idea. Now that I think about it, a large object is trivial in this
sysyem. You dedicate some group of contiguous pages solely to the object. This
results in some potential waste of the last page, which is probably
acceptable. You would not ever need to perform compaction in those pages, just
pointer remapping. When the object eventually dies, you release all the pages
at once.

