Introducing Shenandoah Traversal mode – part I

In this post I want to introduce a (not so very) new GC mode that we call “Traversal GC”. It all started over a year ago when I implemented the ‘partial’ mode. The major feature of the partial mode is that it can concurrently collect a part of the heap, without the need to traverse all live objects, hence the name partial GC. I will go into details of how that works in a later post. First I would like to explain another foundation of Shenandoah’s partial GC, which is the single-traversal-GC, or short Traversal GC.

Let me first show some pictures that explain how Shenandoah works (and in-fact, more or less how other collectors work):

Shenandoah usually runs in one of two modes (switched dynamically depending on automatic ergonomic decisions): First the 3-phase mode:

The cycles are:

  1. Concurrent mark: traversal all live objects, starting from roots, and mark each visited object as live.
  2. Concurrent evacuation: based on liveness information from concurrent marking, select a number of regions, compact all live objects in that region into fresh regions.
  3. Concurrent update-refs: scan all live objects and update their references to point to the new copies of the compacted objects.

Each concurrent phase is book-ended by a stop-the-world phase to safely scan GC roots (thread stacks) and do some housekeeping. That makes 4 (very short, but still measurable) pauses during which no Java thread can make progress.

When GC pressure is high, and GC cycles run close to back-to-back, Shenandoah switches to 2-phase operation. The idea is to skip concurrent update-refs phase, and instead piggy-back it on subsequent concurrent marking cycle:

In other words, we now have:

  1. Concurrent mark: traversal all live objects, starting from roots, and mark each visited object as live. At the same time, when encountering references to from-space, update the to point to the to-space copy.
  2. Concurrent evacuation: based on liveness information from concurrent marking, select a number of regions, compact all live objects in that region into fresh regions.

As before, we still have pauses before and after each phase, now totalling 3 stop-the-world pauses per cycle.

Can we do better? Turns out that we can:

Now we only have one concurrent phase during which we:

  1. Visit each live object, starting from roots
  2. When encountering an object that is in the collection-set, evacuate it to a fresh compaction region
  3. Update all references to point to the new copies.

The single concurrent phase is book-ended by 2 very short stop-the-world phases.

This probably sounds easy and obvious, but the devil lies, as usual, in some interesting details:

  • How to select the collection-set? We have no liveness information when we start traversing.
  • How to ensure consistencies:
    • Traversal consistency: how to deal with changing graph shape during traversal
    • Data consistency: how to ensure writes go to the correct copy of objects, how to ensure reads don’t read stale data, etc
    • Update consistency: how to avoid races between updating of references and ordinary field updates

I will go into those details in a later post.

If you’re interested in trying out the traversal mode, it’s all already in Shenandoah (jdk10, jdk11 and dev branches) and stable enough to use. Simply pass -XX:ShenandoahGCHeuristics=traversal in addition to the usual -XX:+UseShenandoahHeap on the command line. More information about how to get and run Shenandoah GC can be found in our Shenandoah wiki.

Advertisements

How to set up Conversations as alternative to WhatsApp

Note: this article is also available in German.

What is Conversations?

Conversations is an app for Android Smartphones for sending each other messages, pictures, etc, much like WhatsApp. However, there are a number of important differences to WhatsApp:

  • Conversations does not use your phone number for identification, and doesn’t read your address book to find contacts. It uses an ID that looks much like an email address (the so-called Jabber-ID), and you can find contacts by exchanging Jabber-IDs with people, just like you do with email addresses, phone numbers, etc.
  • Conversations uses an open protocol called XMPP, that is used by many other programs on a wide range of systems, for example on desktop PCs.
  • Converations is Open Source, i.e. everybody can inspect the source code, check it for security issues, see what the program actually does, or even modify and distribute it.
  • XMPP builds on a decentralized infrastructure. This means that not one company is in control of it, but instead there are many providers, or you can even run your own server if you want.
  • Conversations does not collect and sell any information from you or your contacts.

There are more differences, but I don’t want to go into detail here, others have already done it, and better (German).

Install Conversations

From Google Play

Conversations is easily installed from Google Play. However, it currently costs 2,39€. I’d recommend everybody who can to buy the it, it supports development of this really good app.

Alternative: From F-Droid

For all those who cannot or don’t want to spend the money, there is another way to get it for free. It is available in the F-Droid. It is an alternative app store, that only distributes Open Source software. In order to do that, you first need to install F-Droid. Then you can start F-Droid and search for Conversations and install it.

Set-up Jabber account

Next step is to set up a Jabber account. You need two things: an ID, and a provider. The first part, the ID, you can choose freely, e.g. a fantasy name or something like firstname.surname, but this is really up to you. In order to find a provider, I recommend this list https://gultsch.de/compliance_ranked.html. The providers at the top of the list have best support for the XMPP features that are relevant for smartphone users. I’d recommend trashserver.net because this supports in-band registration (directly from Conversations) and is very well maintained. If you want to further support the developer of Conversations, I’d recommend an account on conversations.im, this currently costs 8€/year. I think it is worth it, but you have the choice.

If you choose, for example, the ID ‘joe.example’ on the provider ‘provider.org’, then your Jabber-ID is joe.example@provider.org. When you’re decided on a Jabber-ID, you can easily register an account by starting Conversations, entering the Jabber-ID in the set-up screen, check the box ‘register new account on server’, enter your preferred password 2x and confirm it.

Adding contacts

Adding contacts is different than WhatsApp. You have to manually add contacts to your roster. Tap on the ‘+’ symbol next to the little people icon, enter your contact’s Jabber-ID and confirm it. Now you’re ready to start chatting. Have fun!

Conversations mit Jabber als Alternative zu WhatsApp einrichten

Diesen Artikel gibt es auch in Englisch.

Was ist Conversations?

Conversations ist eine App für Android Smartphones, mit der man sich gegenseitig Nachrichten, Bilder, etc schicken kann, sehr ähnlich wie WhatsApp. Es gibt allerdings ein paar wichtige Unterschiede zu WhatsApp:

  • Conversations verwendet nicht Deine Telefon-Nummer zur Identifikation, und nicht Dein Adressbuch um Kontakte zu finden. Deine ID sieht aus wie eine Email-Adresse (Deine sogenannte Jabber-ID), und Kontakte findest Du indem Du Deine Jabber-ID mit Bekannten austauschst, genau wie bei Email-Adressen oder Telefonnummern auch.
  • Conversations benutzt ein offenes Protokoll, genannt XMPP, das von vielen anderen Programmen auf vielen verschiedenen Systemen genutzt werden kann, z.B. auch auf Desktop PCs.
  • Conversations ist Open Source, d.h. jeder kann den Quellcode einsehen, und z.B. auf Sicherheitsprobleme überprüfen, oder sich vergewissern was das Programm eigentlich macht, oder es ändern, etc.
  • XMPP baut auf eine dezentrale Infrastruktur, das bedeutet daß nicht ein Unternehmen alles kontrolliert, sondern daß es viele verschiedene Anbieter gibt, oder man z.B. selbst entsprechende Server betreiben kann, wenn man möchte.
  • Conversations sammelt und verkauft keinerlei Informationen über Dich und Deine Kontakte.

Es gibt noch einige andere Unterschiede, aber ich will hier nicht im Detail darauf eingehen, das haben andere schon viel besser getan.

Conversations installieren

Von Google Play

Conversations lässt sich ganz einfach von Google Play installieren. Es kostet dort allerdings momentan 2,39€. Ich möchte allen, die die Möglichkeit haben empfehlen, die App zu kaufen, ihr unterstützt damit die Entwicklung dieser wirklich guten App.

Alternative: Von F-Droid

Allen, die Google Play nicht nutzen können, oder die aus welchen Gründen auch immer nicht 2,39€ dafür zahlen können oder möchten, sei die Installation über F-Droid ans Herz gelegt. F-Droid ist ein alternativer App Store, der aussschliesslich Open Source Software bereitstellt. Dazu muss man sich zunächst F-Droid installieren. Dann kann man in der F-Droid App nach ‘Conversations’ suchen, und dort installieren. Das ist kostenlos und legal.

Jabber-Account einrichten

Als nächstes musst Du einen Jabber Account einrichten. Dazu benötigst Du zwei Dinge: eine ID, und einen Anbieter. Den ersten Teil, die ID, kannst Du selbst wählen, z.B. einen Phantasienamen, oder etwas wie vorname.nachname, aber das ist wirklich Dir überlassen. Um einen Anbieter zu finden, empfehle ich diese Liste: https://gultsch.de/compliance_ranked.html. Die Anbieter ganz oben unterstützen die meisten Features die für Smartphone-Nutzer wichtig sind. Ich kann trashserver.net empfehlen, da dieser Server die Registrierung direkt aus der Conversations-App heraus unterstützt, und auch sonst sehr gut gewartet wird. Wenn Du dem Entwickler von Conversations zusätzlich Unterstützung zukommen lassen möchtest, dann ist ein Account auf conversations.im empfehlenswert, dies kostet aber momentan 8 Euro im Jahr. Ich finde, das ist es wert, aber das muss jeder selbst entscheiden.

Wenn Du z.B. die ID ‘max.mustermann’ auf dem Anbieter ‘anbieter.de’ aussuchst, ist Deine Jabber-ID: max.mustermann@anbieter.de . Wenn Du Dich für eine ID und einen Anbieter entschieden hast, dann kannst Du ganz einfach einen Account einrichten, indem Du Conversations startest und im Einrichtungs-Bildschirm die gewünschte Jabber-ID eingibst, das Häkchen bei ‘Neues Konto auf Server erstellen’ aktivierst, Dein gewünschtest Passwort 2x eingibst und dann auf ‘Weiter’ tippst.

Kontakte hinzufügen

Anders als in WhatsApp musst Du in Conversations Deine Kontakte selbst hinzufügen. Dazu einfach auf das Symbol mit dem ‘+’ neben Männchen tippen, die Jabber-ID des Kontaktes eingeben, fertig. Und dann kannst Du loschatten! Viel Spaß!

Shenandoah GC in Fedora 24

About a month ago, Fedora 24 has been released. This is an important milestone for Christine and myself, because it includes Shenandoah in its Java VM by default. We consider this our first official release!

If you want to try it out, it’s very simple: pass -XX:+UseShenandoahGC at the cmd line, and your favorite application runs with Shenandoah!

Please report back any issues that you find to the shenandoah-dev mailing list.

Shenandoah Performance

I wanted to attent FOSDEM two weeks ago, but couldn’t because I was sick, in bed with fever. I should have done a presentation about Shenandoah. Unfortunately, my backup Andrew Dinn also became sick that weekend, so that presentation simply didn’t happen. I want to summarize some interesting news that I wanted to show there. About Shenandoah’s performance.

When I talked about Shenandoah at FOSDEM 2015, I didn’t really announce any performance numbers, because we would have been embarrassed by them 🙂 We spent the better part of last year optimizing the heck out of it, especially the barriers in the C2 compiler, and here we are, with some great results.

SPECjvm2015

Ok. This doesn’t really exist. The last SPECjvm release was SPECjvm2008. Unfortunately, SPEC doesn’t seem to care about SPECjvm anymore, which means the last Java version that runs it without any modifications is Java7. We did some small fixes, that allows it to run with Java9 too. This invalidates compliance of the results. But they are still tremendously useful for comparison. So here it comes:

SPECjvm2015

This was run on a 32 core box with 160GB of RAM, giving the JVM 140GB of heap. Exact same JVM and settings with G1 and Shenandoah. No special tuning parameters.

In terms of numbers, we get:

Throughput:   Shenandoah: 374 ops/m  vs. G1: 393 ops/m (95%, min 80%, max 140%)
Pauses:          Shenandoah: avg: 41 ms, max 202 ms                     G1:               avg: 240 ms, max 1126 ms

This means, throughput of Java apps, running with Shenandoah is on average 95% that of G1, depending on the actual application, it’ll range from around 80% to around 140%. However, pause times on such large heaps are significantly better with Shenandoah!

SPECjbb2015

SPECjbb2015 measures throughput of a simulated shop system under response time constraints, or service level agreements (SLAs). It measures ‘max-jops’ which is maximum throughput of the system without SLA, and critical-jops, which is throughput of the system under a restrictive SLA. Here are the numbers, G1 vs. Shenandoah, same machine and JVM settings as above:

SPECjbb2015This basically confirms the results that we got from SPECjvm2008: general throughput in the area of 95% behind G1, but much better pause times, reflected in a much higher score of critical-jops.

Other exciting news is that Shenandoah is now stable enough that we want to encourage everybody who’s interested to try it out. The nice folks at Adopt-OpenJDK have set up a nightly build from where you can grab binaries (Shenandoah JDK8 or Shenandoah JDK9). Enjoy! (And please report back if you encounter any problems!)

Shenandoah OpenJDK project

It’s been a long while since I posted anything. In the meatime we’ve made lots and lots of progress with Shenandoah. The most important news of the week is that Shenandoah has now been accepted as an official OpenJDK project. We’ve got a website, a mailing list, mercurial repositories, and a wiki page. The code hasn’t been moved yet, I am in the process of doing it. It will first land in our JDK9 forest (as we’re doing our main development there) and will be backported to JDK8 in a while.

Just to give you a summary of what happened in the last 1.5 years since I posted anything (bad me): we’ve implemented all that we wanted (runtime, interpreter, C1 and C2 barriers, weak-reference support, JNI critical regions support, System.gc() support, and lots of other smallish things), it’s fairly stable (still expect bugs here and there, but should run quite a lot of your code), performance looks good (on average, ~90% of what G1 does, some benchmarks as bad as ~70% relative to G1, some beat it by ~150%), pause times on largish heaps are significantly better than with G1 (but still not quite where we want it to be).

If you’re interested, subscribe to the new list, watch out for the code to land (or grab it from IcedTea in the meantime), and give it a try! Any feedback is welcome, as always! 🙂

The Shenandoah Code

Last weekend I’ve been talking about the Shenandoah GC at FOSDEM 2014. I announced the availability of the Shenandoah source code and project pages. Until Shenandoah becomes a proper OpenJDK project, it will be hosted on IcedTea servers. We currently have:

We also filed a JEP for Shenandoah, here you can find the announcement and discussion on hotspot-gc-dev.

If you are interested in the slides that I prsented at FOSDEM, you can find them here.

Implementation-wise we’re making good progress. Concurrent evacuation is working well and support for the C1 compiler is almost done.