Java Memory-Leaks mit plumbr finden

Geschrieben von everflux am April 2nd, 2013

Java hat einen schlechten Ruf, auch heute noch: Langsam, braucht zu viel Speicher, umständlich und und und. Das mit dem Speicher ist bei Java gerade bei Webanwendungen (oder Enterprise-Anwendungen) wirklich so eine Sache. Bei nicht wenigen Projekten habe ich gesehen, dass Java Server (Tomcat, Websphere, …) Nachts regelmäßig durchgestartet werden, um dafür zu sorgen, dass es keine Speicherprobleme gibt.
Die Speicherprobleme kommen jedoch nicht von Java selbst, sondern es handelt sich in der Regel um Memory-Leaks. Diese können auch bei manueller Speicherverwaltung (malloc/free vs. Garbage Collection bei Java) auftreten. Eine ganz besondere Form von Speicherlecks sind sogenannte “Permgen-Leaks”. Permgen ist der Speicherbereich der Sun/Oracle Hotspot VM in der z.B. Java Klassen gehalten werden. Solange diese gebraucht werden, bleiben die Klassen geladen. Klassen gehören zu einem Classloader, eine Klasse, die von verschiedenen Classloadern geladen wurde, stellt sich der Anwendung in der Regel als verschiedene Klassen dar. Die damit einhergehenden Probleme wenn das innerhalb der selben Anwendung passiert können nochmal ganz andere sein.
Bei Web-Anwendungen gibt es einen Classloader, der für eine deployte (oder deutsch “verteilte”, “zur Verfügung gestellte”) zuständig ist. Wird die Anwendung undeployt, jedoch der Container (Tomcat z.B.) nicht heruntergefahren sollte dennoch der Speicher der Anwendung, insbesondere auch der Permgen Speicher, wieder freigegeben werden.
Passiert das nicht, führt das unweigerlich nach mehreren Re-Deployments zu einem “Out of Memory: Permgen” Problem.
Aus diesem Grund werden dann oft die Server zusammen mit dem Deployment neu gestartet. Das kann Zeit kosten und ist in meinen Augen die Garantie dafür, dass die Speicherlecks auch dauerhaft nicht behoben werden: Die Entwickler spüren die Schmerzen nicht, das senkt die Motivation etwas zu tun. Bewegt man sich in Richtung Continuous-Integration oder gar Continuous-Deployment kommt ständiges Neustarten von Servern nicht in Frage: Es dauert lange, Caches sind danach kalt.
Bisher habe ich Speicherlecks daher stets gejagt: VisualVM (Sun/Oracle, Teil des JDK), Eclipse MAT (SAP Entwicklung, OpenSource) oder auch YourKit (Profiler, kommerziell) und findbugs (OpenSource) haben mir gute Dienste geleistet. Kommt man ohne EAR aus, hilft auch der in Tomcat integrierte Memory-Leaks-Prevention-Listener, ähnliches bietet auch Jetty. Nicht immer hat man reines WAR deployment oder nur Java Servlets, und die manuelle Suche kann sehr zeitintensiv werden.
Weiterlesen »

Netbeans + git = merge commit bei pull?

Geschrieben von everflux am März 16th, 2013

Netbeans unterstützt derzeit keine interaktive Auswahl der Optionen “merge commit” oder “rebase” wenn bei einem git pull kein fast-forward möglich ist. Dazu gibt es diesen Netbeans bug: http://netbeans.org/bugzilla/show_bug.cgi?id=213855

Als kleiner Work-Around ist es jedoch mit git Bordmitteln möglich, das Default-Verhalten von git selbst anzupassen. Dazu kann man auf einem Branch das Verhalten konfigurieren, z.B. dem master branch:

git config branch.master.rebase true

Ich hoffe dieser kleine Netbeans Tipp hilft auch anderen Usern :)

James Bond – nicht gezahlt?

Geschrieben von everflux am Oktober 30th, 2012

Der neue James Bond ist (wieder einmal) ein Meisterwerk an Product-Placement. Heineken hat einen mittleren zweistelligen Millionenbetrag investiert, habe ich gelesen.

Doch wie ist das eigentlich, wenn nicht bezahlt wird. Insbesondere wenn eine dramatische Szene “versehentlich” ein Produkt eines Nichtzahlers, womöglich sogar eines Konkurrenten zu sehr ins Bild rückt?

Da gibt es eine ganz pragmatische Lösung in guter alter James Bond Manier: Dafür sorgen, dass es keiner sieht.

Weiterlesen »

Ubuntu boot partition voll

Geschrieben von everflux am September 14th, 2012

Wenn Ubuntu sich beklagt, dass die boot Partion bald voll ist, dann muss man etwas unternehmen.

Das ist eigentlich sogar sehr einfach!

Die boot Partition beinhaltet den Kernel (das Betriebssystem) und eine RAM-Disk, auf der Treiber und minimale Start-Scripte liegen. Diese werden benötigt, um Treiber und spezielle Geräte wie eine verschlüsselte Startpartion einzurichten.

Nun kann der Speicher, der für diese Dinge benötigt wird, sehr stark wachsen. Vor allem wenn viele Kernel-Updates herausgegeben werden, oder man Virtualbox oder NVIDIA Treiber installiert hat, die viel Speicherplatz benötigen. Wenn man sicher ist, dass mit dem aktuellen Kernel alles funktionier, dann kann man getrost alte Linux Kernel Installationen entfernen um Speicherplatz auf der boot Partition zu sparen.

Ich mache das folgendermaßen:

Termial öffnen

sudo apt-get purge linux-image<tab><tab>

Nun erhält man verschiedene Versionen zur Auswahl.  Ich nehme dann immer alle bis auf die neuesten drei. So kann man bei Problemen nochmal eine Version zurück gehen.

Zum Beispiel entferne ich dann folgende Kernel um auf der boot Partition mehr freien Speicherplatz zu schaffen:


sudo apt-get purge linux-image-3.2.0-23-generic linux-image-3.2.0-24-generic linux-image-3.2.0-25-generic linux-image-3.2.0-26-generic linux-image-3.2.0-27-generic

Analog für die “headers” und andere Image Pakete.

Schon ist Platz für neue Ubuntu Updates, Kernel Updates und Module wie Virtualbox oder proprietäre Grafiktreiber wie NVIDIA.

DB: Sicherheit bei Textfeldern

Geschrieben von everflux am August 26th, 2012

Die Deutsche Bahn hat so bei Online Tickets auch vorgesehen, diese Online zu stornieren. Jedoch ist das nicht unbedingt vollautomatisch moeglich, z.B. falls das Ticket bereits den Gueltigkeitszeitpunkt erreicht hat.
Dann muss da auch eine Begruendung eingegeben werden, ich hatte einen ICE der direkt mit 15 Minuten Verspaetung starten sollte, so dass ich Anschluesse nicht mehr so erreicht haette, dass ich zu humanen Zeiten zuhause gewesen waere.
Genau das wollte ich der DB auch mitteilen. An den offensichtlich zum Schutz gegen Injektions-Angriffen eingebauten Vorgaben bin ich dann jedoch erstmal gescheitert…

Ubuntu 12.04: OpenJDK selber bauen

Geschrieben von everflux am Mai 12th, 2012

Ubuntu ist für mich die präferierte Entwicklungsplattform, sicherlich geht es vielen anderen (Java) Softwareentwicklern ähnlich. Und im Sinne von OpenSource möchte man OpenJDK auch auf dem eigenen Rechner übersetzen können. Das ist z.B. nützlich, wenn man selber das Java mal patchen oder debuggen möchte, aber auch um z.B. die neuesten Entwicklungen von Java 8 auf dem eigenen System ausprobieren zu können.

Im Vergleich zu früher macht der Übergang von Ubuntu zu MultiArch auf 64 bit Systemen etwas Probleme, jedoch ist das mit einem “gewusst wie” schnell erledigt. Als Vorbedingung muss ein Java (OpenJDK 6/7, Oracle JDK) installiert sein. Ich habe in meinem Fall unter /usr/lib/jvm/jdk1.7.0 ein Oracle JDK installiert.

Als nächstes benötigt man Mercurial, die hgforest extension und ein paar Bibliotheken für den Build. Ich installiere hgforest im Home-Verzeichnis, wer das nicht mag, muss die Pfade entsprechend anpassen:

apt-get install mercurial
apt-get install gawk g++ libcups2-dev libasound2-dev libfreetype6-dev libx11-dev libxt-dev libxext-dev libxrender-dev libxtst-dev libfontconfig1-dev
hg clone https://bitbucket.org/pmezard/hgforest-crew/overview/ "$HOME/hgforest"

Die hgforest Erweiterung fuer Mercurial traegt man direkt in der Mercurial Konfiguration ein, indem man die Datei ~/.hgrc editiert und folgenden Abschnitt ergaenzt (auch hier gilt dann ggf. den Pfad anzupassen)

[extensions]
forest=~/hgforest/forest.py

Nun clont man die OpenJDK Sourcen aus dem Updates-Repository für OpenJDK 7:

hg fclone http://hg.openjdk.java.net/jdk7u/jdk7u openjdk7u

Dazu solle man ca. ein Gigabyte Speicher auf der Festplatte einplanen. Bei dem ersten Build sollte auch eine Internet Verbindung vorhanden sein, da ggf. noch zusätzliche Libraries nachgeladen werden. Nun starten wir den Build:

cd openjdk7u
unset JAVA_HOME
export LANG=C
export ALT_BOOTDIR="/usr/lib/jvm/jdk1.7.0"
export ALLOW_DOWNLOADS=true
export EXTRA_LIBS=/usr/lib/x86_64-linux-gnu/libasound.so.2
make sanity && time make

Zu beachten ist hier, dass die Environment-Variablen “ALLOW_DOWNLOADS” und “EXTRA_LIBS” gesetzt sind. Letztere rührt daher, dass auf 64 Bit Systemen mit Ubuntu das OpenJDK Build-System die Libraries (noch) nicht von selbst richtig findet. Auf 32 bit Systemen wird das nicht nötig sein, und vermutlich auch in zukünftigen OpenJDK Versionen direkt implementiert sein.

Der Build Output sollte in etwa so aussehen:

########################################################################
##### Build time 00:10:30 jdk for target(s) sanity all docs images #####
########################################################################


#-- Build times ----------
Target all_product_build
Start 2012-05-12 11:40:32
End   2012-05-12 12:04:01
00:01:27 corba
00:10:15 hotspot
00:00:18 jaxp
00:00:27 jaxws
00:10:30 jdk
00:00:32 langtools
00:23:29 TOTAL
-------------------------


real    23m30.532s
user    32m10.625s
sys    2m24.617s

Im Ordner “build” befindet sich dann der Ordner “linux-amd64″ in dem sich das frisch kompilierte Java auch ausführen lässt:

./build/linux-amd64/bin/java -version
openjdk version "1.7.0-internal"
OpenJDK Runtime Environment (build 1.7.0-internal-tkruse_2012_05_12_11_40-b00)
OpenJDK 64-Bit Server VM (build 23.0-b21, mixed mode)
Übrigens lässt sich genauso einfach auch Java 8 (OpenJDK 8 ) auf einem Debian oder Ubuntu System übersetzen, das Repository ist unter http://hg.openjdk.java.net/jdk8/jdk8/ zu finden.

jQuery anchor hash Selektor

Geschrieben von everflux am April 21st, 2012

In älteren Versionen von jQuery konnte man einen Selektor für den hash Wert von Links schreiben. (Der Hash Wert ist der Teil hinter “#” in einem Link element, man kann damit verschiedene Bereiche in einer Seite anspringen.)

Das sah mit jQuery 1.2.6 z.B. so aus:

$("a[hash='#sprungMarke']");

Bei neueren jQuery Versionen ist das nicht mehr so explizit möglich. Dafuer gibt es jedoch Selektoren mit denen man auf Inhalte und partielle Inhalte von Attributen matchen kann. Hiermit ist es dann wieder möglich auf den Hash Wert zu matchen, denn es handelt sich dabei gerade um das Ende des “href” Attributes eines Links.

Mittels “$” kann man das Suffix-Matching für den Wert eines Attributes machen.

Damit sieht das dann so aus:

$("a[href$='#sprungMarke']");

Die neuen, flexibleren, Selektoren von jQuery können also Arbeit sparen, wenn man sich ihrer Mächtigkeit bewusst ist.

Netbeans TDD Produktivität

Geschrieben von everflux am April 21st, 2012

Test driven development ist inzwischen schon fast ein alter Hut. Um so mehr ist es wichtig, dass die Produktivität stimmt. Hält man sich an bestimmte Namenskonventionen, so unterstützen alle modernen IDEs schnelles Umschalten zwischen Test-Code und Produktionscode.

Dazu nennt man seine Testklasse genauso wie die Class-under-test, beispielsweise “FibonacciTest” falls die eigentliche Klasse “Fibonacci” heißt. Mittels Control-Shift-T kann man in Netbeans dann zwischen den beiden Klassen umschalten. Heute habe ich noch was gelernt: Control-F6 startet den Unit test – und zwar auch dann, wenn man ihn nicht fokussiert hat, also in der eigentlichen Klasse im Editor ist. (“Fibonacci” in diesem Beispiel)

Das spart unnötige Kontext-Switche, macht einfach Spaß und bringt Produktivität. Mein Tipp: Ausprobieren!

Mit Alt-F6 startet man übrigens alle Tests zu einem Projekt. (Falls einem nicht komische Ubuntu Tastenkürzel dazwischenfunken.)

Grub bootet nicht – fail von recordfail?

Geschrieben von everflux am März 10th, 2012

Ubuntu setzt den Grub / Grub2 Bootloader standardmäßig ein. Solange er funktioniert ist auch alles prima. Bei Desktop Rechnern gibt es sowieso kein Problem – hier kann man notfalls manuell eingreifen und im Boot Menü seine Lieblingsoption auswählen oder ganz von Hand booten.
Bei Servern sieht das schon etwas anders aus. Normalerweise sind diese nicht an eine Konsole angeschlossen, oder stehen sogar (sehr) weit weg.
Ein Feature von Grub ist, dass sich der Bootloader merken kann, ob ein Startvorgang erfolgreich war. Wenn der schief geht, wird beim nächsten Start nicht direkt gebootet, sondern das Grub Menü bleibt stehen, damit der Anwender eine andere Option auswählen kann. Das ist für einen Desktop Rechner sicherlich genau das gewünschte, und Ubuntu zielt primär auf Desktop User. Der Anwender kann jetzt eine Rettungs-Konfiguration auswählen, oder es einfach nochmal versuchen.
Wenn bei einem Server ein boot jedoch schief geht – z.B. weil genau da ein Reset/Stromausfall o.ä. stattfindet – dann steht der Server. Bis jemand etwas von Hand einstellt. Das kann dann eine längere Downtime bedeuten.
Ich kann damit besser leben wenn der Server im Falle eines Defekts endlos immer wieder Boot-Versuche unternimmt, als wenn er stehen bleibt weil einmal etwas blöd gelaufen ist. Das ist auch ganz einfach zu ändern:
Man öffne die Datei /etc/grub.d/20_header und ersetze folgenden Abschnitt

if [ "\${recordfail}" = 1 ]; then
  set timeout=-1

Durch diesen Abschnitt:

if [ "\${recordfail}" = 1 ]; then
  set timeout=30

Danach noch ein "update-grub" und in Zukunft wird im Falle eines Bootfehlers 30 Sekunden auf Eingaben gewartet und sonst ein neuer Boot-Versuch gestartet.

Stromverbrauch des Samsung Galaxy Nexus

Geschrieben von everflux am März 3rd, 2012

Man gewöhnt sich ja daran, dass man alle Nase lang das Handy tauschen muss. Sei es für ein neueres Betriebssystem oder … nein. Eigentlich nur dafür. Die Bildschirmauflösung des Galaxy Nexus ist sicherlich nett, aber der primäre Grund das aktuellste zu kaufen ist für mich aktuelle Software. Und der wichtigste Grund eben kein neues zu kaufen ist die Akku-Laufzeit.
Nach einem Tag mittlerer Nutzung kann das gute direkt an die Ladestation. Neben technischen Durchbrüchen kann es aber auch helfen die Hintergrundprogramme etwas zu zügeln.
Bei mir hat es geholfen die Google-Plus Anwendung von der Synchronisation auszunehmen. Dazu kann man bei dem Handy unter “Synchronisierung” den jeweiligen Google Account anklicken und die Google Plus App von der Hintergrundsynchronisation ausnehmen. Subjektiv hat das rund 10% gebracht und seit dem bin ich mit dem Galaxy Nexus auch sehr zufrieden.
Dennoch darf es im nächsten Gerät wirklich etwas mehr Akkupower sein.


http://everflux.de/
Copyright © 2007, 2008 everflux. Alle Rechte vorbehalten. All rights reserved.