Posts mit dem Label Java werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Java werden angezeigt. Alle Posts anzeigen

Mittwoch, 4. Juni 2025

Spring Boot und die Annotationshölle

 Spring und Spring Boot sind sehr gute Frameworks und haben aus meiner Sicht zu Recht J2EE ersetzt. Einer der Probleme von Spring Boot Applikationen ist der Annotationsjungel. Es gibt in vielen Projekten Klassen mit 5, 6 oder 7 Klassenannotationen auch Methoden oder Felder haben machmal 3 Annotationen.  Und für den Programmierer ist das schwer zu verstehen:

  1. Was bedeutet die Annotation?
  2. Aus welchem Framework stammt sie: Spring, Hibernate, Lombok, Shedlock, ... ?
  3. Wie funktionieren sie?

Hier ein paar wichtige Annotationen, wie sie funktionieren. 

Spring Sterotype Annotationen wie Service oder Component funktionieren via Klassenname. Paketnamen sind egal, das heisst, wenn ich zwei Klassen mit dem selben Namen habe die aber in anderen Paketen sind, dann führt das zu einem Konflikt.

Lombok Annotationen wie Getter, ... funktionieren über Code Ergänzungen. Das ist meist unkritisch. 

Spring Annotationen wie Retry, Transactional oder Shedlock Annotationen funktionieren über Wrapper oder Proxy Klassen  (Hello Grails and Groovy). Diese Annotationen sind in der Verwendung kritischer, weil sie nur von Aussen funktionieren. Das heisst, die annotierte Methode muss public oder im default Scope sein und der Aufruf muss aus einer anderen Klasse erfolgen. Dann läufts wie erwartet.

Und jetzt die gefährlichsten Annotationen, Anootationen ohne Funktion, die nur die Lesbarkeit erhöhen, wie z.B. JetBrains NotNull nicht zu verwechseln mit  Jakarta Validation NotNull oder Lombok NonNull. JetBrains NotNull dient  nur der Dokumentation und ggf. der statischen Code Analyse.

So, know your annotations. Happy coding life. 

Donnerstag, 2. Februar 2023

Managing Dependencies for Micro Services

Dependency Hell, das kennen viele Softwareentwickler oft aus mature Projekten. Was bedeutet das fuers Projekt?

  1. Es kann nicht auf aktuelle Versionen von Libs migriert werden, Java eingeschlossen. Dadurch bleiben nuetzliche Funktionen verschlossen.
  2. Das Projekt ist statisch wie Beton und nur unter sehr grossem Zeitauswand aenderbar.
  3. CVEs koennen nicht behoben werden.

Um Dependencies effiktiv zum meisten und obige Schwaechen zu umschiffen, hier ein paar Best Pracices im Umgang mit Dependencies.

  1. Goldene Regeln
    1. Less is more
    2. Convention over configuration
  2. Versuche mit moeglichst wenig Konfigurationen auszukommen.
  3. Versiuche moeglichst wenig Dependencies zu benutzen.
  4. Benutze Parents wenn moeglich.
  5.  Benutze Dependeny Management (Maven) wenn es moeglich ist.
  6. Benutze nur fixe Versionen von Libs wenn sie nicht im Parent verfuegbar sind.
  7. Wenn du Excludes/Includes brauchst z.B. um CVEs zu fixen, dann hinterlasse einen entsprechenden Kommentar mit der CVE Nummer. So kann diese Konfiguration spaeter sehr einfach entfernt werden.
  8. Update regelmaessig deine Dependencies um keinen Wartungsstau aufkommen zu lassen. Du kannst leicht einen Check Step in der Build Pipeline einbauen die dir Anzahl der outdated Libs ausgibt.
  9. Aktuelle Libs verbessern die Sicherheit, aktuelle Libs haben weniger CVEs. 
  10. Pruefe ob Dependencies noch benutzt werden
    1. Grep isy dein Freunf fuer Compile Scope Dependencies: grep -r com.strange-package src/
    2. Organize your imports
  11. Das Build file ist genauso ein Teil deines Softwareprojetes wie der Code selbst.

 

Samstag, 1. August 2020

Java Streams

Ich habe mich lange gedrückt um einen Artikel über Java Streams zu schreiben, jetzt nach Jahren ist es so weit. 

Als ich das erste Mal Java Streams sah, ich glaube es war in einem Meetup, kamen mir zwei Gedanken:
  1. Wow, cool
  2. Welches Problem wird durch Java Streams gelöst.#
  3. Parallelisierung für lau
In den nächsten Jahren sickerten die Streams so in die allgemeine Java Programmierung. Streams waren ja nicht Neues, ich habe Streams (Pipes) exzessiv mit BASH and Splunk eingesetzt.  

Meine anfänglich Begeisterung sank recht schnell auf den Nullpunkt. Java Streams schienen in der Praxis mehr neue Probleme zu verursachen, als sie lösten, und welches Problem sollten Streams nochmal lösen.

Jetzt nachdem der Hype weitergezogen ist, hier in aller Ruhe ein paar Tipps und Antworten zu Java Streams. 

Frage: Welches Problem löst Java Streams?

Streams sind eine weitere From oder Alternative zu Schleifen (for, while). Sie bieten zwei Vorteile gegenüber den normalen Schleifen. Bei grossen Datenmengen kann man Streams parallelisieren, was auf Multi-Prozessorsystemen einen Geschwindigkeitsvorteil bringt. Dazu zwei Anmerkungen, in Cloud Umgebungen ala Marathon, Kubernetes, AWS - schaut in euere Configs ob ihr Überhaupt mehr als eine CPU habt, wenn nicht, bringt die Parallelisieren von Streams nichts. Die zweite Anmerkung, nur bei grossen Datenmengen ist die Parallelisieren sinnvoll, weil sonst der Overhead durch die Verteilung des Codes und der Daten über mehrere Cores die Geschwindigkeitsgewinn der Parallelisieren aufrisst.

Hier ein Beispiel für eine super simple Parallelisierung mit Java Streams: https://www.adam-bien.com/roller/abien/entry/java_8_from_ordinary_for


Das zweite Vorteil von Java Streams gegenüber normalen Schleifen ist, das die Abarbeitung strukturierter erfolgt (stream -> (filter -> map)* -> collect). Das war für mich eher selten das Problem, aber es eindeutig ist das ein Vorteil von Java Streams. Das Problem sind nicht die Streams, das Problem sind die Programmier die mit Java vertraut sind. Sie fangen jetzt an das bekannte Exception Handling und Verzweigungen in den Streams einzubauen. Das ist generell ein Fehler oder besser der Fehler beim Umgang mit Streams. 

Streams behandeln nur positive Fälle. Ein Exception Handling oder ein Handling von Alternativen führt zu extrem schwierig zu lesendem Code. So etwas sollte in einem zweiten Stream gemacht werden. Streams sind verzweigungslos. Das macht sie so elegant und verständlich. 

Java Entwickler die es gewohnt sind Exceptions nahe am Ursprung zu behandeln, müssen umdenken und diese Funktionen in Filter und einem zweiten Stream auslagern.


Zusammenfassung:

  1. Streams sind ein sinnvolles Pattern für die Softwareentwicklung
  2. Wer Pipes toll fand wird Streams lieben
  3. Streams sind verzweigungsfrei zu bauen, entsprechende Filter, ggf. Mappings und alternative Streams sind umzusetzen

Samstag, 25. Juli 2020

Video: The Future of Programming von Robert C. Martin

Robert C. Martin aka Mister Clean Code von seiner besten Seite. Ein schönes Video über die Vergangenheit, den aktuellen Stand und die Zukunft der Sofwareentwicklung. Aber ich will nicht spoilern, seht selbst.

 

Montag, 13. Juli 2020

Gitlab Badges for Maven Jacocoo Test Coverage

  1. Integrate Jacoco into your Maven pom.xml.
  2. Add into your file .gitlab-ci.ymlecho -n "Total:" ; cat target/site/jacoco/index.html | grep -o 'Total[^%]*%' | grep -o -E '[0-9]+%$
  3. Add Badge in Gitlab under Setting.
  4. Gitlab scan the console for the Regex you given in Point 3.



Dienstag, 6. August 2019

Java, XML und Performance

XML ist ein populäres Datenformat für den Datenaustausch zwischen Systemen. Der Vorteil von XML ist, es gibt sehr stabile Parser. Aber wie sieht es mit der Performance aus? Folgende Aufgabe: Einlesen einer XML Datei mit 100T Elementen,  die einige Unterelemete besitzt, die Tiefe ist 4, Dateigrösse 60Mb, Java 8.

Zum Performancevergleich wurde mit einem Subset von 350 Elementen gearbeitet.

Test 1: Java, XML, DOM, Xpath, 350 Elemente in Datei

  1. Laufzeit pro Element: 20ms
  2. Verhältnis XML Parsen/DB Speichern: 25, das XML Verarbeiten verbraucht primär die Zeit
  3. Geschätzte Gesamtlaufzeit: 33 min


Test 2: Java, XML, DOM,  Jaxen 1.2 Xpath, 350 Elemente in Datei

  1. Laufzeit pro Element: 3ms
  2. Verhältnis XML Parsen/DB Speichern: 15, das XML Verarbeiten verbraucht primär die Zeit
  3. Geschätzte Gesamtlaufzeit: 5 min
  4. Jaxen Xpath ist deutlich schneller als das normale Java Xpath

Beide Tests waren erfolgreich. Jetzt der Test mit voller Datenmenge.

Test 3: Java, XML, DOM,  Jaxen 1.2 Xpath, 100T Elemente in Datei
  1. Manueller Abbruch des Test, weil die Laufzeit unglaublich schlecht war.
Test 3: Java, XML, DOM,  Xpath, 100T Elemente in Datei
  1. Manueller Abbruch des Test, weil die Laufzeit unglaublich schlecht war.
  2. Performance ist aber besser als Jaxen.
  3. Bei einer Detailanalyse sieht man das die Laufzeit für die XPath Evaluierung nach oben schnellen, das obwohl ausreichen RAM (XMX) vorhanden ist. Der Schluss daraus ist, das die Auswertung von XPath ausdrücken eine hohe Komplexität hat, es werden scheinbar Listen durchlaufen. Übertragen auf relationale DBs, XPath Evaluierung entsprechen sequential Scans. Java XPath kann also nicht die Element-Adresse im Speicher berechnen, sondern muss sie suchen, indem (mehrere) Listen sequentiell durchlaufen werden.
Zusammenfassung
  1. Die Verarbeitung grosser XML Dateien mittels DOM und XPath ist ineffizient. Das gilt wahrscheinlich auch für andere DOM basieret Formate wie JSON.
  2. Jaxen XPath ist deutlich schneller als Java XML XPath für kleine und normale DOMs.
  3. Lösungen: 
    1. Alternativen wäre Streaming XML via SAX oder StAX.
    2. Wechsel von XML zu CSV.

Freitag, 7. Juni 2019

Datenschutz: Es dürfen keine persönlichen Daten geloggt werden.

Ein Hauptquelle für das Exponieren von persönlichen Daten ist das Logging. Programmierer loggen einfach Objekt zu Debug-Zwecken oder in Fehlerfall. Diese Daten landen in Log-Dateien oder im ELK Stack. Dort gehören sie nicht hin.

Hier ein Weg dies zu verhindern. Für das Logging wird in der der Regel die toString() Methode in Java benutzt. Diese muss man bei allen Klassen deren Objekte persönlich Daten enthalten überschreiben. Hier ein Beispiel:

    @Override
    public String toString() {
        return "DATENSCHUTZ";
    }
    

Mit diesem einfachen Overwrite der toString() Methode verhindert man das persönliche Daten geloggt werden und gleichzeitig kann man die Verwendung potentiell kritischer Aufrufe im Log finden und diese Stellen entfernen. Bei Bedarf sollte man auch die Methode asString() genauso überschreiben.

Mittwoch, 2. Mai 2018

Prüfen von Java Libs auf bekannte Verwundbarkeiten

Es gibt ein gutes Tool mit dem man Java Libs auf bekannte OWASP Schwachstellen prüfen kann. Dieses Toll gib es als Plugins für diverse Build-Werkzeuge. Man kann es aber auch Out-Of-The-Box nutzen:

Installation:
brew install dependency-check

Für Grade gibt es ein Plugin, wenn man dieses nich nutzen möchte kann man alle Dependencies herunterladen, mit folgenden Grade Task:
task getDeps(type: Copy) {
   from sourceSets.main.runtimeClasspath
   into 'runtimeX/'
}


Ausführen und Erzeugen eines Report mit gefundenen Verwundbarkeiten
dependency-check --project haupt --scan runtimeX/ --suppression config/dependencyCheck/suppressions.xml --suppression config/dependencyCheck/suppressNetty.xml


In dem Report findet man gelegentlich False-Positive Warnungen, diese kann man mit Hilfe der Saupression-Dateien unterdrücken.


Link:

  1. https://www.owasp.org/index.php/OWASP_Dependency_Check

Samstag, 17. März 2018

Warum ich keine mehr Konfigurationsdatei brauche.

In der heutigen Softwareentwicklung, also ich meine Java, Docker und die Cloud, brauche ich keine Konfigurationsdateien mehr. Warum? Ganz einfach, eine Konfigurationsdatei ermöglicht es, das Setup von Programmen an die eigenen Bedürfnisse anzupassen und die Software neu zu starten. So machen es viele Programme wie der Apache Server oder Postgres. Hier machen Konfigurationsdateien Sinn.

Wenn ich mich im Cloud Umfeld bewege und individuelle Wegwerf-Software mit Docker erstelle und deploye, dann gibt es diesen Anwendungsfall nicht mehr, dass ich ein Konfiguration anpasse und dann die Software neu starte.

Im der Welt von Docker, Cloud und Continuoude Deployments kann ich die Konfiguration im Code ändern, ins GIT einchecken und warten bis meine Continuouse Deployment Pipeline mir nach wenigen Minuten eine neue Softwareversion ausgerollt hat. Fertig, jetzt brauch ich eine Properties oder YAML Dateien mehr. Das ist für Softwareentwickler einfacher als sich via VPN auf Hosts, und dann auf Docker Container anzumelden und Änderungen an der Konfiguration durchzuführen. In den letzen Jahren in denen ich mich in diesem Umfeld bewege ist mir dieser Fall nicht vorgekommen.

Aber, Secrets wie Access-Keys, Passwörter oder Benutzernamen gehören natürlich nicht so plain in den Code und auch nicht ins GIT. Solche geheimen Daten kann man dann ggf. in verschlüsselten Konfigurationsdateien speichern.

Mittwoch, 26. April 2017

Docker: Oracles Java auf einem Ubuntu Image

Das geht ganz einfach, bei den meisten gängigen Images bekommt man OpenJDK oder die Images sind nicht gewartet. Also hier eine relativ einfache, mögliche Lösung:

FROM ubuntu:latest
MAINTAINER mirko.ebert@g****.com

RUN apt-get update; apt-get -y upgrade
RUN apt-get -y  install software-properties-common
RUN add-apt-repository ppa:webupd8team/java
RUN apt-get update
RUN echo debconf shared/accepted-oracle-license-v1-1 select true |  debconf-set-selections
RUN echo debconf shared/accepted-oracle-license-v1-1 seen   true |  debconf-set-selections
RUN apt-get -y  install  oracle-java8-installer


RUN apt-get clean

Donnerstag, 8. Dezember 2016

Vortrag bei der Java User Group Dublin - Fotos

Jetzt sind die wirklich guten Fotos von meinen Vorträgen, IoT mit Tinkerforge und Software Robustheit, bei der Java User Group Dublin da:
https://www.flickr.com/photos/139932355@N08/albums/72157674941628376

Danke an die beiden netten Hosts: Barry und Gerry und an die Firma Tinkerforge für die Unterstützung.





Dieser Briefkasten (Dublin, Temple Bar) stammt aus der Zeit als George König war. GR bedeutet George Royal und nicht wie es einem die Iren erzählen George Rules. Man beachte das der Briefkasten irisch Grün und nicht Englisch rot ist!


Sonntag, 31. Juli 2016

Tinkerforge IoT First Steps Java Project launched on Github

I launched the first steps Java project for learning Tinkerfor ge and IoT (Github).

It uses following hardware as my simple and low cost starter kit:

  • Master Brick
  • Segment Display 4x7 Bricklet
  • Teperature Bricklet
  • Ambient Light Bricklet
  • Accelerometer Prickelt


The newbie can start with some experiments or challenges:

  • Hello World
  • Simple Themometer
  • Thermomenter and Clock
  • Small weather station with temeperatur, time and illumination
  • Resource saving programming with Call Backs/Listeners
  • Ambient Light sensor as contactless display light switch
  • Accelerometer as contactless switch
Code examples helps to realize the challenges.

Tinkerforge Weather Station published on Github

Tinkerforge is electronics framework for software developers. It's a good starting point for your own Internet of Things (IoT).  So I decide to bye me a starter kit. I choose the weather station kit.

Now, after some time I publish my Tinkerforge Weather Station Java Project on Github (Link). Its simple and robust. It uses callbacks to recognize on sensor changes. and runs over days without problems. It measures humidity, air pressure, ambient light and temperature. The temperature is measured indirectly via chip temperature of the humidity bricklet. Special features are, switching the display light depending on ambient light, show alternating date and time and show warnings because of to low or high humidity. If you put your hand over the ambient light sensor, the sensor works as contactless light switch.


If you are looking for more information on Tinkerforge, you can read the book (Kindle, german only) from Sven Ruppert: Einführung in die Heimautomatisierung: IoT mit Tinkerforge.


Montag, 5. Januar 2015

Erstellen eines eigenen Grade Plugins

Gradle lässt sich wie fast jeden andere System mittels Plugins erweitern. Ein Plugin ist nichts weiter als eine Jar-Datei die man am besten auf einen Nexus deployed. Über diesen Nexus wird dann das Plugin für andere Gradle-Projekte bereitgestellt. Hier ein typischer Ausschnitt aus der Datei build.gradle.

buildscript {
        repositories {
                maven { url "http://nexus.ebert-p.com:8080/content/groups/public" }
                maven { url "http://repo.gradle.org/gradle/libs-releases-local" }
        }

        dependencies {
                classpath "de.otto:lpt-gradle-plugin:0.0.3-SNAPSHOT"
        }
}


apply plugin: "lpt-gradle"

Mit repositories wird definiert wo nach den dependencies gesucht werden soll. Mit  dependencies wird die Jar-Datei beschrieben, die Code, hier ein eigenes Gradle-Plugin enthält. Mit apply wir das Gradle-Plugin auf das aktuelle Projekt angewendet. Wie Gradle von dem Plugin-Namen zur ausführbaren Klasse kommt wird unten beschrieben.

Zuerst muss das Plugin programmiert werden. Womit man diese Jar-Datei baut ist egal, es ist auch möglich ein Gradle-Plugin mit Maven zu bauen. Wenn man das Gradle Plugin mit Java entwickeln möchte, muss man seine Haupklasse von org.gradle.api.Plugin ableiten.

package com.ebertp.gradleplugin.wpt;

import org.gradle.api.Plugin;
import org.gradle.api.Project;


public final class WptTest implements Plugin<Project> {

@Override
public void apply(Project project) {
System.out.println("Hello Gradle Plugin User, this is Java.");
}


}


Als Zweites muss ein Mapping vom Plugin-Namen zur Hauptklasse definiert werden. Dafür muss eine Properties-Datei mit dem Namen des Plugins unter resources/META-INF/gradle-plugins angelegt werden.

src/
├── main
│   ├── java
│   │   └── com
│   │       └── ebertp
│   │           └── gradleplugin
│   │               └── wpt
│   │                   └── WptTest.java
│   └── resources
│       └── META-INF
│           └── gradle-plugins
│               └── lpt-gradle.properties
└── test
    ├── java

    └── resources

In dieser Properties-Datei wird das Mapping des Plugin-Names auf die Java Klasse definiert:

implementation-class=com.ebertp.gradleplugin.wpt.WptTest


Wichtig, der Plugin-Name hat nichts mit dem Namen der Jar Datei zu tun!

Jetzt muss nur noch eine Har-Datei gebaut werden und auf den Nexus hochgeladen werden.

Dienstag, 11. November 2014

Neues Java Projekt gelauncht: Simple Guitar Tuner

Ich habe auf Github ein kleines Projekt simpleguitartuner gelauncht und das erste Release gebaut. Mit ihm kann sehr einfach die Saiten einer Gitarre stimmen. Im Gegensatz zu den anderen Tuningprogrammen ist dieses sehr präzise bezüglich der Frequenzen. Das Programm wird gestartet: java -jar simpleguitartuner-0.0.1.jar und gestoppt mit CTRL + C. Einfacher geht es nicht. Nach dem Start gibt die Saite an, die man stimmen möchte, dann spielt man die Saite und bekommt das Ergebnis und den Sollwert sehr genau angezeigt. Das geht so lang, bis man das Programm beendet.

Hier die Daten:

Mittwoch, 22. Oktober 2014

Optimierung von If Else in Java

If-Else Konstrukte mit zwei Exit-Points kann auf zwei verschiedene Weisen in Java formuliert werden:
Hier beide Varianten, einmal mit und einmal ohne Kommentare. Dann befindet sich der zweite Exit-Point im Else-Zweig. Welche dieser beiden Varianten ist performanter?

Die Antwort ist, es egal. Aus beiden Code-Varianten wird identischer Byte-Code erzeugt:

Mittwoch, 27. August 2014

Java GC Optimierung

Mit Java 8 sind einige JVM Optionen jetzt als Standard gesetzt. Das sind folgende GC Tuning Massnahmen:

  • -XX:+UseCompressedOops 
  • -XX:+DoEscapeAnalysis
Das erste Flag verringert den Speicherverbrauch auf 64 Bit Systemen.

Nachzulesen bei Oracle unter folgendem Link: http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html


Und hier noch ein paar hilfreiche Links zum Thema GC:

Sonntag, 3. August 2014

Java auf einem QNAP TS-110, der zweite Versuch

Nachdem mein erster Versuch gescheitert war auf meinem QNAP TS-110 Java zu installieren, gibt es jetzt gut Nachrichten. QNAP bietet jetzt ein funktionsfähiges Java 8 als JRE. Es lässt sich einfach via QNAP App-Manager installieren.

Und hier der Beweis im Terminal:

Jetzt ist das QNAP vollständig, einen Tomcat kann man auch installieren, Damit habe ich einen kleinen Entwicklungsserver. Allerdings darf vom QNAP TS-110 nicht zu viel erwarten. Das RAM ist mit 256MB sehr begrenzt und die CPU (Marvell 800MHz) auch. Kleinere Anwendungen sollten aber möglich sein. Als nächstes Projekt kann das QNAP die Tinkerforge Wetterstation bedienen.

Mittwoch, 11. Juni 2014

Welche Java GC Version wird benutzt? Oder wie identifiziere ich den Java GC?

Java bietet eine reiche Auswahl an GC Varianten:

  1. SerialGC
  2. ParallelGC
  3. ParallelOldGC
  4. CMS GC
  5. G1 GC
Zusammen mit den möglichen Parametern hat man einen sehr grossen Suchbereich um den optimalen GC mit den optimalen Einstellungen zu finden. GC Optimierungen haften immer etwas mythisches an. Es gibt Supertricks, die bei genauerem Hinsehen und Testen oft überholt sind. Es hilft nur ein ebenes Testsetting aufzubauen und selbst zu messen.
Damit stellt sich die Frage welcher GC wird denn verwendet, ich gebe doch keinen an. Da hilft die Kommandozeile weiter:

java  -verbose:gc -XX:+PrintGCDetails


Das Ergebnis der Konsole ist spezifisch für die entsprechenden GCs.

SerialGC -XX:+UseSerialGC

Es ist ein genrationaler GC mit den drei Generationen: New Generation Tenured Generation und der Perm Generation. Die New Generation teilt sich in die Bereiche Eden, From und To.







ParallelGC -XX:+UseParallelGC

Es ist ein genrationaler GC mit den drei Generationen: Young Generation, Old Generationen Perm Generation. Die New Generation teilt sich in die Bereiche Eden, From und To. Es lässt sich leicht vermuten, dass der ParallelGC eine weiterentwickelte, parallele Variante des SerialGC ist. Es soll durch die Benutzung von allen Kernen die Dauer der GCs verkürzen. Er macht also nur Sinn, wenn man über mehrere CPU-Kerne verfügt.


CMS GC -XX:+UseConcMarkSweepGC

Es ist ein genrationaler GC mit den drei Generationen: Young Generation, Concurrent Mark Sweep Generationen und der Perm Generation. Die New Generation teilt sich in die Bereiche Eden, From und To. 

Der CMS GC basiert auf den Erfahrungen des ParallelGC. Hier werden möglichst viele GC Schritte (Mark, Sweep) parallel ausgeführt ohne ein Stop-The-World auszuführen. Das heisst man kann ungenutzte CPU Kerne für den GC nutzen, wenn man denn welche hat. Der Overhead des CMS GC ist grösser als des ParallelGC aber durch die Benutzung zusätzlicher CPU Kerne wird dieser negative Effekt überkompensiert, so das der CMS bei vilene normalen Anwendungen die Performance der Anwendung verbessert aber die CPU Usage erhöht. Er ist also sinnvoll, wenn ich freie CPU Ressourcen habe. Zusätzlich braucht der CMS immer freien Speicher für seine Operationen. Er kann nicht den ganzen Speicher ausnutzen.

G1 GC -XX:+UseG1GC

G1 GC Details unter Java 7

G1 oder Garbage First ist der zu letzt entstandene GC. Er setzt auf dem CMS GC auf und ändert die Speicherbenutzung für die Young Generation und die folgende Generation, mit dem Ziel die Speicheroperationen zu minimieren und damit die GC Laufzeiten zu reduzieren. Hier teil sich der Speicher in den Garbage First Heap und die bekannte Perm Generation. Der Garbage First Heap kennt da die Unterteilungen in Young und Survivors. Für den G1 GC gelten die selben Performance und Load Anmerkungen wie für den CMS GC, wobei der G1 leicht bessere Werte als der CMS erzielen sollte.

Unter Java 8 wurde der G1 überarbeitet, das hatte zur Folge, dass der Perm Generation jetzt Metaspace heisst.

Fazit

Genereller Tip, der für 80% aller Anwendungen passt. Macht keine GC Einstellungen, lasst sie weg und nutzt die gewonnene Zeit um die Software robuster zu machen. Tipp 2: Setzt die aktuellste Java Version ein. Ein aktuelles Java mit einem neuen GC schliessen viele Optimierungstricks ein, also nur die sinnvollen.
GC Optimierungen bleiben aufwendig. Nur bei High Performance oder High Load Applikationen sind GC Optimierungen sinnvoll. Aber generell gilt immer, zu erste messen, dann optimieren.

Weitere Informationen zum Java GC:

  1. http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/
  2. http://www.angelikalanger.com/Articles/EffectiveJava/27.GCTuning/27.GCTuning.html
  3. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html
  4. http://www.fasterj.com/articles/oraclecollectors1.shtml