2016-03-27 7 views
3

Ist es in Ordnung, eine Bibliotheksdatei direkt nach dem Laden mit der Funktion system.loadLibrary() zu löschen? Hier ist das Szenario ...Löschen einer temporären Datei nach dem Laden in JVM

Wir verwenden JNI, um das DomainSocket-Dienstprogramm zu verwenden, das in C-Sprache geschrieben wird, um von einer Java-App aus aufzurufen. Wir packen die .SO-Dateien in das gleiche jar und verwenden ein Dienstprogramm, um eine temporäre Datei im Dateisystem zu erstellen und laden Sie die .SO mit der loadLibrary-Funktion. Wir verwenden die Datei File.createTempFile(), die eine eindeutige temporäre Datei erstellt. Wir verwenden die Datei deleleOnExit(), um die temporäre Datei beim Herunterfahren von JVM zu löschen.

In einer eigenständigen Anwendung auf JVM funktioniert das einwandfrei. Aber wir haben ein Problem bei der Bereitstellung in Web-Containern wie Tomcat, da mehrere Anwendungen auf derselben JVM ausgeführt werden können. Zunächst wird für jede bereitgestellte App eine temporäre Datei erstellt. Das eigentliche Problem ist, dass die temporäre Datei nicht gelöscht, sondern neu erstellt wird, wenn die App gestoppt und gestartet oder erneut bereitgestellt wird. Alle temporären Dateien werden gelöscht, wenn die JVM heruntergefahren wird (Tomcat neu gestartet).

Wir experimentierten mit einer Lösung, um die temporäre Datei nach der loadLibrary() zu löschen. Dies scheint gut zu funktionieren. Eine neue temporäre Datei wird beim Neustart erstellt und direkt nach dem Laden gelöscht.

Wollte überprüfen, ob jemand einige Hinweise/Vorschläge hat?

Wir möchten nicht den common/lib-Mechanismus verwenden, um die .SO-Dateien nur einmal pro Container zu laden, da wir diese .SO-Dateien Teil der Anwendung machen wollen.

Antwort

0

Ist es in Ordnung, eine Bibliotheksdatei direkt nach dem Laden mit der Funktion system.loadLibrary() zu löschen?

Nein. Das Betriebssystem kann die Bibliothek jederzeit "entladen" und muss die Binärdatei möglicherweise erneut von der Festplatte laden. Wenn Sie die Datei löschen (und sie wird vom Prozess nicht gehalten), erhalten Sie ein sehr merkwürdiges Verhalten ... wahrscheinlich etwas wie einen "BUS-FEHLER" oder eine andere kaum erklärbare Bedingung.

Auch wenn die Bibliothek nicht aus dem Speicher gelöscht und erneut von der Festplatte geladen wird, haben verschiedene Betriebssysteme Flags für "Lazy Loading" und andere Dinge, die Sie in eine Race Condition Situation bringen können. Disk-Bibliothek-Artefakt, bevor der gesamte Code tatsächlich von ihm geladen wurde.

Wir verwenden die Datei File.createTempFile(), die eine eindeutige temporäre Datei erstellt. Wir verwenden deleteOnExit(), um die temporäre Datei beim Beenden von JVM zu löschen.

Dies scheint ein vernünftiger Ansatz, abgesehen von den Problemen, denen Sie begegnen. Verwenden Sie statt File.createTempFile einen vorhersagbaren Dateinamen an einem vorhersagbaren Ort (z. B. /tmp/libgoodstuff.so)? Wenn Sie das tun, müssen Sie nur eine einzelne Datei erstellen (und die Löschung planen) (pro Bibliothek, die Sie laden möchten).

[Ich] wollte überprüfen, ob jemand einige Hinweise/Vorschläge hat?

die .so Datei in der Anwendung platzieren wird hart sein, zu verwalten, wenn Sie wirklich sehr gut Ihre Zielumgebungen kennen. Zum Beispiel müssen Sie sicherstellen, dass Ihre Zielarchitektur und das Betriebssystem korrekt sind usw.

Die Quintessenz ist, dass native Bibliotheken als Teil einer verteilbaren Anwendung sind ein Schmerz im Nacken mit Java und sollte vermieden werden, es sei denn, es gibt keine anderen Optionen.

+0

Auf welches Betriebssystem beziehen Sie sich, wenn Sie sagen, dass Bibliotheken zu jeder Zeit entladen werden können? – apangin

+0

@apangin Kein bestimmtes Betriebssystem, das ich im Sinn hatte. Aber es gibt keine Anforderung von POXIX usw., dass der Code geladen bleibt und daher das plattenbasierte Artefakt frei verschwinden kann. Ich würde erwarten, dass "undefined behavior" das Ergebnis des Ladens ist und dann eine shared-library von der Platte löscht. –

+0

Nun, ich weiß nicht, Betriebssysteme (zumindest unter den von Oracle JDK unterstützt), die zum Absturz einer Anwendung führen, wenn eine gemeinsame Bibliothek gelöscht wird. Normalerweise verweigert das Betriebssystem das Löschen (Windows) oder hebt den Dateinamen auf (Linux), wobei die Dateidaten auf dem Datenträger verbleiben. Das Entfernen der Datei wirkt sich nicht auf die Speicherzuordnungen dieser bereits geöffneten Datei aus. – apangin

0

Ja, dieser Ansatz funktioniert möglicherweise, aber mit gewissen Einschränkungen.

Wenn System.loadLibrary aufgerufen wird, wird die entsprechende .so-Datei in den Prozessadressraum kopiert. Wenn Sie die Datei entfernen, wird die entsprechende dentry sofort entfernt, aber nicht die inode. Das heißt, der Dateiname ist nicht verknüpft, aber die Dateidaten werden beibehalten, bis der letzte Verweis auf die Datei freigegeben wird.

Auf diese Weise installieren Paketmanager Updates. Sie können ausführbare Dateien und freigegebene Bibliotheken löschen, selbst wenn sie von laufenden Prozessen verwendet werden. Das Betriebssystem stellt sicher, dass die laufenden Programme weiterhin die alte Version der Bibliotheken verwenden, während die neuen Programme neue Versionen laden.

Dieser Ansatz ist jedoch nicht portierbar. Es funktioniert auf Linux, aber nicht auf anderen Betriebssystemen und nicht auf jedem Dateisystem (z. B. Windows oder FAT). Daher würde ich dies nicht empfehlen, es sei denn, Sie kennen die verwendete Betriebssystemplattform.

+0

Wir haben einen Haken mit nur einer .SO-Datei im Web-Container. Die .SO-Datei, die von einer Webanwendung geladen wurde, kann aufgrund des Classloaders nicht von einer anderen Webanwendung geladen werden. Tomact weist jeder webapp einen eindeutigen classloader zu und lädt das * selbe * .SO funktioniert nicht ... – user2089210

+0

@ user2089210 Richtig, ich habe diesen Teil verpasst. Wenn Sie also die Anwendung nicht für plattformübergreifende Übertragung benötigen, können Sie Bibliotheken sofort nach dem Laden löschen. Mit einer JNI-Bibliothek ist die Anwendung ohnehin nicht portabel. – apangin

Verwandte Themen