Java, JNA und was dabei raus kommt

Java ist zwar eine Insel, aber auch die Sprache und ihre dazugehörige Runtime lädt aber auch manchmal zum abwandern ein. Zugegebenermaßen war es meine eigene Unfähigkeit. Dennoch ist das Problem nicht gerade einfach zu beheben, vor allem wenn Google einem x-tausend Treffer beschert, die alle zwar das gleiche Resultat haben, aber unterschiedliche Ursachen.

 

Bei mir war es jedenfalls so. Ich habe eine Applikation gebaut, die JNA benutzt, um an die unteren Betriebssystem-Funktionen zu gelangen. Einige davon benötigen Pointer, etwas was es bei Java nicht gibt. Dafür gibt es mit JNA eine ähnliche aber objekt-orientierte Version. com.sun.jna.Memory heißt die Klasse, aus der man auch flux ein Objekt erzeugen kann, sogar im Konstruktor angegeben, wieviel Speicher dafür angefordert werden soll. Man soll nur ja nicht versuchen, die Kernel32-Funktion LocalFree() darauf anzuwenden. Das verursacht nämlich den folgenden Effekt:

 

- LocalFree() gibt den zu Grunde liegenden Speicherbereich des Objekts frei

- Das Objekt selbst ist natürlich noch verfügbar.

- Beim Verlassen des Scopes (Funktion beendet) wird die Referenz auf das Objekt verworfen, im Garbage Collector wird der Speicher dementsprechend markiert.

- Irgendwann, wenn der GC mal Lust und Laune hat, wird das Objekt aufgeräumt, dabei natürlich der zugehörige Speicher freigegeben.

 

Und dort knallts dann. Klassische Double-free die eine Speicher-Schutz-Verletzung nach sich zieht. Das Debugging war die Hölle, da der Fehler dort nie auftrat. Nur in der regulären vorgesehenen Anwendung der Applikation hat sich der Fehler bemerkbar gemacht.

Es äußert sich darin, das in der hs_err_pid Datei der Zeiger auf den Finalizer-Thread zeigt. So ähnlich sieht die Log-Datei aus:

http://bugs.gentoo.org/attachment.cgi?id=223263

Kurz um: Überlasse der JRE das freigeben von Speicher, dann hast du keine Probleme.


Trackback
No comment yet
Post your comment

Categories