Tag Archive for 'java'

Java VisualVM

Ich bin mal wieder auf der Suche nach Speicherlöchern und anderen unangenehmen Dingen. Da stellt sich doch heraus, dass Java VisualVM auch ein recht brauchbares Tool ist.

Dates

[via geekandpoke]

Indiana Jones und die Suche nach dem verlorenen Speicher

Ein bisschen Suche nach passenden Tools für mein Memory Leak Problem brachte ein paar Interessante Seiten und Tools zum Vorschein.

“Your pager hasn’t been sleeping well. It periodically wakes you up in the middle of the night to tell you that your server is firing off “OutOfMemoryError” messages. Worse still, your significant other forcibly relocated you to the couch and told you not to return until your pager stops buzzing.

Sound familiar? If so, you may have a case of memory leak induced insomnia, but fortunately we’ve got a cure for what ails you. This tutorial will teach you everything you need to know to ease your suffering, including what memory leaks are, why they happen, and how to diagnose and fix ‘em.[...]“

Nützlich sind hierbei der gcviewer um das Java GC-Log zu visualisieren und der Memory Analyzer (MAT) um Java Heap Dumps zu analysieren.

Das GC-Log kann man mit folgenden Java-Parametern erstellen:

-verbose:gc
-XX:+PrintGCTimeStamps
-XX:+PrintGCDetails
-Xloggc:<logfile>

Alles weitere, und wie man Heap-Dumps erzeugt, wird in obigem Artikel sehr anschaulich erklärt.

Java Memory Leaks

Ich bin zwar gerade auf der Suche nach einem anderen Memory Leak, aber das klingt ja auch interessant… besonders wenn man noch mit Java 1.4 arbeitet.

“Why is my Java program leaking memory when I call run() on a Thread object?”

The issue is that at construction time, a Thread is added to a list of references in an internal thread table. It won’t get removed from that list until its start() method has completed. As long as that reference is there, it won’t get garbage collected.

So, never create a thread unless you’re definitely going to call its start() method. A Thread object’s run() method should not be called directly.

A better way to code it is to implement the Runnable interface rather than subclass Thread. When you don’t need a thread, call

myRunnable.run()

When you do need a thread:

myThread = new Thread(myRunnable);
myThread.start();

[via stackoverflow.com]

Jar Manifest lesen

unzip -p file.jar META-INF/MANIFEST.MF | less

Damn it

“[...] File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine.”

FileLock

Mehr schlechte Ideen aus der Java Welt

Als Java-Entwickler macht man sich ja kaum Gedanken um Speicher und sonstiges. Ich mache mir z.B. auch nicht immer Gedanke was mit den Streams passiert, die ich so im laufe der Zeit öffne. Ein:


BufferedInputStream buffered = new BufferedInputStream(
  new FileInputStream(file));
buffered.close();

bewirkt z.B., dass beim Schließen des BufferedStream auch gleichzeitig der FileInputStream geschlossen wird. Ist ja auch gewollt so.

Etwas kniffliger wird es leider mit dem SharedFileInputStream aus javax.mail.util. Dieser benutzt RandomAccess Files, und dass führt schnell zu Fehlern wenn man folgendes macht:


MimeMessage mime = new MimeMessage(
  null, new SharedFileInputStream(file));
processMail(mime);

Hier wird leider beim Aufruf von processMail(mime), das unter dem SharedStream liegende RandomAccess File geschlossen, was mit einer “java.io.IOException: Bad file descriptor” Exception belohnt wird. Hier lohnt es sich, eine Referenz auf den Stream zu halten und diese erst selbst zu schließen, wenn die processMail() Methode zurückkommt.

Base64

Ich habe gerade die Wahl zwischen dem sun.misc.BASE64Encoder der leider im sun.*-Package liegt, was nicht wirklich plattformunabhängig und portabel ist, oder der javax.mail.internet.MimeUtility.encode() Funktion, aus dem javamail Paket, die egal ob Windows oder Linux jede Zeile mit einem CRLF beendet. Nicht wirklich ne tolle Auswahl…

Nachtrag:
Ok… im Fall E-Mail ist der MimeUtility Encoder wohl doch recht sinnvoll, weil ja als Linebreak eh ein CRLF vorgeschrieben ist.

Bedingter Konstruktor in Java

Bei Verwendung des Super-Konstruktors in Java, muss dieser immer zuerst aufgerufen werden. Also geht z.B. sowas nicht:

public foo(String bar) {
  if (bar != null) {
    super(bar);
  } else {
    super("blub");
  }
}

Was aber anscheinend geht, ist folgendes:

public foo(String bar){
  super(bar != null ? bar : "blub");
}

Nicht, dass man das unbedingt verwenden sollte… aber es geht.

Nützlich

javap – der Java Class File Disassembler

javap -s CLASS

… wenn man sich für die Signaturen interessiert.