Tag Archives: Java

Singletons auf die faule Art

Wir hatten heute eine kurze Diskussion über Singletons und die Art und Weise ihrer Erzeugung, speziell wenn man sie faul (lazy) erzeugen möchte. Die Wikipedia hat dazu diesen schönen Eintrag – On Demand Holder Idiom:

In software engineering, the Initialization on Demand Holder idiom (design pattern) is a lazy-loaded singleton. The idiom can be implemented in both single-threaded/serial and concurrent environments, but care must be taken to correctly implement the idiom under concurrent conditions.

Ganz besondern wichtig ist die Erklärung, warum Lazy in diesem Fall so und nicht anders funktioniert:

The implementation relies on the well-specified initialization phase of execution within the Java Virtual Machine (JVM); see section 12.4 of Java Language Specification (JLS) for details.

When the class Something is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class.

G1 – Garbage First Collector

Für das Sun JDK deutet sich ein neuer Garbage Collector an, der ein anderes Herangehen hat und damit lange  Pausen noch deutlicher als der CMS vermeiden soll. Dem geneigten Leser sei dieser Artikel empfohlen: The Garbage First Collector!

Im JDK 6v14 könnten wir ihn vielleicht sehen. Ich bin schon ganz aufgeregt, da ich mittlerweile oft und viel mit GC-Internas hantiere… keine Wunder bei Lasttests gegen 120 CPUs mit Java drauf.

Java und Virtuelle Server (VPS)

Wer sich einen virtuellen Server gemietet hat und sich quält, Java vernünftig zum Laufen zu bringen, dem sei dieser Artikel ans Herz gelegt: Java Web Hosting HowTo – vServer memory and Java heap size trouble.

Java Virtual Machines and Linux virtual Servers do not play well with each other all the time. Some tweaking and configuration will be necessary to get it working and optimize the use of the (memory) resources.

Die VPS / Virtuellen Server haben leider die Angewohnheit, den Speicher als zu gross zu melden. Sie melden den Gesamtspeicher des Hosts und nicht den Speicher des Virtuellen Servers. Deswegen schlägt Java gnadenlos zu, und versucht sich reinzuoptimieren. Die einzige Lösung ist die Limitierung des Speichers schon beim Start von Java mit -Xms und -Xmx, um die Selbstoptimierung von Java zu umgehen.

Softreferenzen gehen jederzeit

Softreferenzen (soft references) in Java sind eine tolle Sache, denn es lassen sich tolle Caches und Notfallszenarien damit bauen. Was kaum jemand weiß, dass Softreferenzen nicht nur im Falle von akuter Speicherknappheit freigegeben werden, sondern durchaus auch früher. Letzteres kann zu unerwarteten Nebenwirkungen führen, speziell mit Blick auf Caching.

Soft references are kept alive longer in the server virtual machine than in the client. The rate of clearing can be controlled with the command line option -XX:SoftRefLRUPolicyMSPerMB=, which specifies the number of milliseconds a soft reference will be kept alive (once it is no longer strongly reachable) for each megabyte of free space in the heap.

The default value is 1000 ms per megabyte, which means that a soft reference will survive (after the last strong reference to the object has been collected) for 1 second for each megabyte of free space in the heap. Note that this is an approximate figure since soft references are cleared only during garbage collection, which may occur sporadically.

Quelle: JDK 6 Garbage Collection Tuning Guide

Nachtrag: Erwähnenswert ist auch dieser Blogeintrag von Jeremy Manson.

Sparen beim String bauen

Viele Java-Programmiere denken oft beim Schreiben Ihres Codes wenig über Müll nach. Natürlich nimmt man zum Bauen eines Strings aus vielen kleinen Puzzleteilen einen StringBuilder. Den StringBuffer nimmt man nicht mehr, weil der im Regelfall unnötig synchronisiert ist. Schliesslich löst das im Java Memory Model ab JDK 5 eine Synchronisation mit dem Hauptspeicher aus (JSR-133), die wir überhaupt nicht wollen.

Einen kleinen Trick für unnötige Objekt-Erzeugung und damit für weniger Müll im System, gerade wenn immer wieder Strings gebaut werden müssen, ist die korrekte initiale Größe des StringBuilders. Ein new StringBuilder() reserviert zunächst nur ein Array mit 16 Characters. Wenn wir also recht viel zusammenbauen, muss mehrmals eine neues grösseres Array (2 * ggw. Grösse + 1) erzeugt und der Inhalt umkopiert werden.

Wer also weiss, dass er ca. 100 Zeichen aneinanderhängt, der lässt sich gleich einen StringBuilder mit Grösse 120 geben – new StringBuilder(120) – und spart damit das Anlegen von drei Arrays und drei Copy-Operation ein. Gerade bei intensiven Operationen mit Strings macht das eine Menge aus.

Wer würde schon bei einem Umzug zuerst mit dem kleinsten Karton anfangen und dann wegwerfen, weil nicht alles reinpasst? Man schätzt doch am Anfang schon vernünftig ab, wie groß der Karton sein sollte.

Java Concurrency – A Tutorial

Heute habe ich eine wunderbare Webseite zum Thema Java Concurrency gefunden. Jakob Jenkov hat hier viele interessante Themen zur parallelen Programmierung mit Java zusammengefasst. Ein Bookmark wert und in einer ruhigen Minute unbedingt mal lesen.

Java Concurrency – A Tutorial

Java was one of the first languages to make multithreading easily available to developers. Java had multithreading capabilities from the very beginning. Therefore, Java developers often face the problems described above. That is the reason I am writing this trail on Java concurrency. As notes to myself, and any fellow Java developer whom may benefit from it.

LinkedIn-Architektur

Wer gern mal wissen möchte, wie moderne grosse Webseiten laufen, der kann sich hier die LinkedIn-Architecture anschauen und durchlesen. Und wieder ist Lucene die Search-Engine der Wahl. Interessant ist der LinkedIn-Network-Graph, der in Memory gehalten wird… 12 GB RAM.

Einzig die Behauptung

Garbage Collection pauses were killing them. [LinkedIn said they were using advanced GC’s, but GC’s have improved since 2003; is this still a problem today?]

kann ich nicht glauben. Deswegen wurde die Graph-Engine in C geschrieben. Ich denke mal, da war komplett etwas falsch, wenn der GC austickt.