Probleme mit JNI



  • Hallo miteinander,

    Ich habe folgendes Problem mit JNI:

    Im moment versuche ich, eine Wrapper-Bibliothek zu schreiben, um aus Java heraus eine 3D-Engine ansprechen zu können. Ein ganz einfaches Programm, das ein SDL-Fenster erzeugt, funktioniert auch schon bedingt.
    Allerdings verringern sich die dargestellten Frames pro Sekunde relativ schnell und kontinuierlich von rund 700 (direkt nach dem Start des Renderns) auf 100 und weniger (nach ca. 3-4 Minuten). Ich vermute daher, dass irgendwo ein Memory Leak entsteht. Der benutzte Speicher steigt allerdings relativ langsam (1Mb alle 2 Minuten oder so)

    Im wesentlichen werden auf Java Seite zunächst einige Resourcen geladen, sowie ein FrameListener erstellt. Der FrameListener wird von der nativen Bibliothek dann aufgerufen, wenn das Zeichnen eines Frames gestartet wird bzw. beendet wurde.
    Danach startet durch einen Methodenaufruf der Render-Prozess. Grundsätzlich läuft das ganze Programm anschließend also irgendwo in nativem Code.

    Jetzt meine Frage:

    Kann mir jemand sagen, an welchen Stellen man grundsätzlich beachten muss, wo evtl Objekte wieder freigegeben werden müssen? (Das muss nichts direkt mit meinem Programm zu tun haben).
    Außer bei der Funktion zum starten des Renderns und den Funktionen, die beim FrameListener aufgerufen werden, kehre ich nach einem native call direkt wieder zur Java-Seite zurück.

    Evtl kann das Abfallen der Frames aber auch mit der Wrapper-Bibliothek zu tun haben, die ich kompiliere. Wenn ich sie nicht im Debug-Modus kompiliere, wird sie auf Java-Seite anstandslos geladen. Im Debug-Modus erhalte ich jedoch folgende Exception:

    FATAL ERROR in native method: JNI call made with exception pending
    	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
    	- locked <0x65900370> (a java.util.Vector)
    	- locked <0x6591cec0> (a java.util.Vector)
    	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)
    	at java.lang.Runtime.loadLibrary0(Runtime.java:822)
    	- locked <0x65911d38> (a java.lang.Runtime)
    	at java.lang.System.loadLibrary(System.java:992)
    	at org.ogretest.Main.<clinit>(Main.java:12)
    

    Hier gibts drei mögliche Fehlerquellen:

    1. Die Lib ist zu groß um sie zu laden (Im Debug-Modus: ~30Mb, ohne Debug: 44Kb)
    2. Kann ich überhaupt Debug-Code gegen die Release-Version der 3D-Engine Bibliothek linken?
    3. Irgendwo liegt auf C-Seite noch ein Fehler, der nur in der Debug-Version auftritt/erkannt wird etc.

    Wenn jemand eine Idee hat, woran mein Frameproblem liegen könnte, immer her damit 🙂

    Gruß, Schmelly



  • Kann mir jemand sagen, an welchen Stellen man grundsätzlich beachten muss, wo evtl Objekte wieder freigegeben werden müssen? (Das muss nichts direkt mit meinem Programm zu tun haben).

    Um Sachen wie Speichermanagement brauchst du dich in Java grundsätzlich erst einmal nicht kümmern. Das übernimmt der GC für dich. Aber so wie ich es verstehe, liegt dieses Memoryleak wohl eher nicht auf Java Seite.
    Du kannst ja mal einen Profiler drüberlaufen lassen und dann gucken ob du was findest.



  • Schmelly schrieb:

    3. Irgendwo liegt auf C-Seite noch ein Fehler, der nur in der Debug-Version auftritt/erkannt wird etc.

    Hört sich IMHO böse an!

    Zur Bereinigung schau mal in die JNI Docs von SUN, da steht drin, falls Du auf C-Seite was löschen mußt und falls nicht. Besonders diese String-Umwandlungen sind da übel!



  • So, Memory Leak endlich gefunden 🙂

    In einigen Utility-Functions, die von der nativen Seite aufgerufen werden, habe ich jobject und jclass objekte benutzt. Die jobject Objekte hatte ich schon jedesmal gelöscht, die jclass Objekte jedoch nicht.

    Nun klappts mit rund 800 FPS prima 🙂

    Das Problem, dass ich die Debug-Bibliothek nicht laden kann, habe ich jedoch immer noch 😞


Anmelden zum Antworten