tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
10
ZUGRIFFE
532
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    arglofou arglofou ist offline Grünschnabel
    Registriert seit
    Aug 2011
    Beiträge
    4
    Hallo,

    ich hoffe, mir kann jemand beim einem Speicherproblem mit jacob (JavaCOMBridge) helfen.
    In beiden folgenden Faellen laeuft meine Anwendung irgendwann „OutOfMemory“.
    Vielleicht muss jacob auf bestimmte Weise initialisiert werden?

    -----------------------
    while( true )
    {
    ActiveXComponent _systemControllerProxy = new ActiveXComponent( “String representation of the COM object” );
    _systemControllerProxy.invoke( “a method of the COM object” );
    _systemControllerProxy.safeRelease();
    }
    -----------------------
    Das safeRelease() scheint hierbei nicht auszureichen, den reservierten Speicher wieder frei zu geben.

    Eigentlich moechte ich den Code so ausfuehren, aber hier ist der Speicherverbrauch noch dramatischer (es scheint bei jedem invoke() neue Objekte angelegt zu werden, obwohl nur mit ein und denselben gearbeitet werden soll:

    -----------------------
    ActiveXComponent _systemControllerProxy = new ActiveXComponent( “String representation of the COM object” );
    while( true )
    {
    _systemControllerProxy.invoke( “a method of the COM object” );
    }

    _systemControllerProxy.safeRelease();
    ComThread.Release();
    -----------------------

    Bin fuer jede Hilfe dankbar.
    Viele Gruesse,
    Andreas



    Das folgende Code-Schnipsel nur mit einem Variant-Objekt laeuft in einer Endlos-Schleife z.B. nur dann nicht OutOfMemory, wenn die ComThread.Release()-Methode aufgerufen wird:

    public static void variantMemLeakTest()
    {
    System.out.println("variantMemLeakTest(): starting ...");
    Variant l_variant = new Variant();
    l_variant.safeRelease();
    //ComThread.Release();
    System.out.println("variantMemLeakTest(): finished.");
    }
     

  2. #2
    Avatar von Fabio Hellmann
    Fabio Hellmann Fabio Hellmann ist gerade online Mitglied Brokat
    Registriert seit
    Aug 2011
    Ort
    München
    Beiträge
    494
    Hi,
    also als aller erstes, solltest du bitte -Tags benutzen, damit der Code gehighlited wird.
    Dann solltest du in deinem Code dringenst vermeiden, while(true)-Schleifen zu verwenden. Außer du baust in der while-Schleife noch einen Thread.sleep(...) ein. Aber auch das ist nicht wirklich günstig, da es keine Abbruchbedingung für die Schleife gibt. Dadurch wird die OutOfMemory-Exception schnell ausgelöst.

    Gruß

    Fabio
     
    Bitte die Code-Tags verwenden. Bei Java-Code: [java]...[/java]

    Tutorials:
    Automatisches erzeugen eines Inhaltsverzeichnisses (Javascript)
    JAnimationPanel - Animationen für Swing/AWT
    SWTRatingBar (Bewertungs-Composite) selbst programmieren
    ____________________________________________________________________________
    Über eine Bewertung (Stern links unter dem Beitrag) oder ein Danke freue ich mich sehr.

  3. #3
    genodeftest genodeftest ist offline Mitglied Brillant
    Registriert seit
    Jun 2009
    Beiträge
    870
    Ganz einfach: du erzeugst in einer Endlosschleife neue Objekte, das gibt zwangsläufig ein Speicherproblem.
    Welchen Zweck hat diese Endlosschleife? ich kann das nicht verstehen...
     
    Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
    Code java:
    1
    
    System.out.println("Hallo");
    hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.
    ___________
    Ubuntu Bug #1: Microsoft has a majority market share
    Casecon: Projekt leiser Käse

  4. #4
    arglofou arglofou ist offline Grünschnabel
    Registriert seit
    Aug 2011
    Beiträge
    4
    Hallo Fabio,

    danke fuer die schnelle Antwort und die Hinweise, bin noch neu hier.

    Die while-Schleifen haben nur Beispiel-Charakter, um das Problem vereinfacht darzustellen und mir im Prozess-Explorer den Speicherverbrauch schnell anzuzeigen.

    Eigentlich lege ich mir das ActiveXComponent einmalig zur Laufzeit an und moechte es moeglichst "fuer immer" benutzen.
    Im normalen Einsatz habe ich keine Endlosschleife.
    Damit wollte ich das Problem nur viel schneller sichtbar machen, was sonst mehrer Tage dauert.

    Gruss,
    Andreas
     

  5. #5
    genodeftest genodeftest ist offline Mitglied Brillant
    Registriert seit
    Jun 2009
    Beiträge
    870
    prinzipiell ist es so, dass die JVM eine automatische Speicherbereinigung durchführt, sobald Speicher knapp ist. Allerdings funktioniert diese Speicherbereinigung nur für Java-Objekte. Die ActiveX-API und wahrscheinlich auch Teile von jacob sind in C/C++ geschrieben, auf diesen nativen Code hat die JVM keinen Einfluss, daher kann sie auch keine Speicherbereinigung im Speicherbereich des nativen Codes durchführen. Da du trotzdem Speicherprobleme hast, ist wahrscheinlich die ActiveX-API und/oder jacob schlecht programmiert.
    Aber warum sollte man eine ActiveX-Anwendung mehrere Tage oder gar Wochen ununterbrochen laufen lassen?
    PS: So lange hält wahrscheinlich nicht mal dein Browser durch – ich kann mir kaum vorstellen, dass der nicht auch ein Memory Leak hat.
     
    Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
    Code java:
    1
    
    System.out.println("Hallo");
    hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.
    ___________
    Ubuntu Bug #1: Microsoft has a majority market share
    Casecon: Projekt leiser Käse

  6. #6
    SE Tutorials.de Gastzugang
    Was ich hier komisch finde , auch wenn es nur ein Beispiel ist , wie du auf sowas kommst :
    Code java:
    1
    2
    3
    4
    5
    
    while(true)
    {
    //to-do something
    }
    release()
    Mal davon abgesehen das du sowas garnicht compilen kannst *javac wird hier ein "unreachable statement" bemängeln* würde ich dann gerne mal wissen wie du ren logisch auf die Anahme kommst das irgendwas nach eine endlos-Schleife noch ausgeführt werden könnte ?
     

  7. #7
    arglofou arglofou ist offline Grünschnabel
    Registriert seit
    Aug 2011
    Beiträge
    4
    Hi,

    der Code soll in einem Produktionsumfeld moeglichst viele Tage lang laufen koennen.

    Jacob bietet mir die bequemste Moeglichkeit, aus meinem Java-Framework auf den C++-Code des Systems zuzugreifen, das ich kontrollieren moechte, ohne mich selbst um JNI oder JNA-Overhead zu kuemmern.

    Momentan bin ich noch nicht sicher, ob ich jacob falsch benutze oder ob es fuer meine Zwecke ungeeignet ist.

    Gruss,
    Andreas
     

  8. #8
    genodeftest genodeftest ist offline Mitglied Brillant
    Registriert seit
    Jun 2009
    Beiträge
    870
    Dann solltest du dich nach einer Alternative für jacob und evtl. auch COM/ActiveX umsehen.
     
    Code bitte so einfügen: [java]System.out.println("Hallo");[/java] (Analog für andere Programmiersprachen)
    Code java:
    1
    
    System.out.println("Hallo");
    hilfreich zu Java: Really Big Index, Java ist auch eine Insel Band 1 und Band 2.
    ___________
    Ubuntu Bug #1: Microsoft has a majority market share
    Casecon: Projekt leiser Käse

  9. #9
    Avatar von mccae
    mccae mccae ist offline Senfdazugeber
    Registriert seit
    Dec 2007
    Ort
    Wien
    Beiträge
    226
    Hallo,

    Ich selbst benutze Jacob, und habe keine Probleme damit.

    Mit dem Milestone 4 Release wurde ein Speicherleck behoben (ich weiß jedoch nicht welches).
    Hast du dir eigentlich die Dokumentation zu Jacob durchgelesen und probiert?

    Ich mache das Ganze in etwa so:

    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    
    ComThread.InitMTA(true);
    System.out.println(LoggingUtils.getTimeString() + "COM Thread launched");
     
    ActiveXComponent borealisCom = new ActiveXComponent("AuroraB.Application");
    System.out.println(LoggingUtils.getTimeString() + "Hooked into Aurora Borealis");
     
    Dispatch borealisController = (Dispatch) borealisCom.getObject();
     
    // Ab hier mit dem Controller arbeiten, von mir aus in einer Endlosschleife:
     
    while(true){
        Variant version = Dispatch.call(borealisController, "Version");
        System.out.println(LoggingUtils.getTimeString() + "Version of Aurora Borealis is: " + version.getString());
     
        Variant hres = Dispatch.call(borealisController, "DoorTest");
        System.out.println(LoggingUtils.getTimeString() + "Is sliding door operating as expected?: " + hres.getBoolean());
     
        if(someCondition){
            break;
        }
    }
    // Nach Beenden der Operationen über COM
     
    ComThread.Release();
    ComThread.quitMainSTA();
    System.out.println(LoggingUtils.getTimeString() + "Released COM Thread");

    Es ist jetzt egal, wie viele Variant / Dispatch Objekte ich erstelle.
    Sobald keine Referenzen auf das Java Objekt (mit Ausnahme der Referenz von Jacob) vorliegen, löscht Jacob auch das native Pendant aus der ROT (Running Object Table), und anschließend kümmert sich der Java Garbage Collector um den Rest.

    Warum es bei dir nicht klappt, weiß ich nicht.

    Zu meinem Beispiel: Wichtig ist, dass die Releasemethoden am Schluss IMMER ausgeführt werden, da so manches in einem inkonsistenten Zustand gelassen werden kann. (finally block benutzen, oder ähnlich).
    Zu beachten ist, dass nach dem Release des Threads der Zugriff auf zuvor erstellte Components verloren geht.

    mfg,
    Martin
    Geändert von mccae (24.08.11 um 00:20 Uhr)
     

  10. #10
    arglofou arglofou ist offline Grünschnabel
    Registriert seit
    Aug 2011
    Beiträge
    4
    Hallo Martin,

    dankeschoen fuer deine Tipps.
    Ja, die Dokus zu jacob habe ich mir durchgelesen.
    Nach der Milestone 4 Release will ich noch einmal schauen, ich hatte mir eigentlich eine neue Version heruntergeladen.

    Wie sieht denn dein Speicherverbrauch waehrend der while-Schleife in deinem Code-Schnipsel aus?

    In meinen Testfaellen (inklusive ComThread.InitMTA( true ) und ComThread.quitMainSTA() ) konnte ich das Speicherleck nur dann umgehen, wenn ich die Release-Methoden ausgefuehrt hatte. Natuerlich verliere ich dann die COM-Objekte und muss die Verbindung wieder neu erstellen, was ich vermeiden wollte.

    Gruss,
    Andreas
     

  11. #11
    Avatar von mccae
    mccae mccae ist offline Senfdazugeber
    Registriert seit
    Dec 2007
    Ort
    Wien
    Beiträge
    226
    Hallo,

    Hast du schon einmal nachgeschaut woher bei dir das Speicherproblem kommt?

    Aus dem Heap oder aus dem PermGen?

    Bei mir sieht der Heap in Ordnung aus:
    jacob memory leak-heap.png

    Und hier mein PermGen:
    jacob memory leak-permgen.png

    Man kann es zwar nicht sehen, doch während der geraden Strecke steigt der Speicherverbrauch kontinuierlich um wenige Bytes pro Minute bei ungefähr 2 Jacob Objekten pro Sekunde.

    Jedoch sinkt der verbrauchte Speicher nicht nach Anwenden der Release Methoden.
    Vielleicht müsste ich noch etwas nach der Ausführung warten bis der Speicherverbrauch weiter sinkt - na ja.

    Wenn bei dir das Speicherleck auf dem Heap auftaucht, handelt es sich mit großer Wahrscheinlichkeit um einen Programmierfehler auf deiner Seite.
    Beim PermGen kann es sich jedoch um ein Problem mit Jacob - (oder auch mit der verbundenen Applikation?!) handeln.

    mfg,
    Martin
     

Ähnliche Themen

  1. Memory Leak?
    Von mccae im Forum Java
    Antworten: 1
    Letzter Beitrag: 14.02.10, 23:50
  2. C++ Memory Leak beseitigen
    Von nchristoph im Forum C/C++
    Antworten: 7
    Letzter Beitrag: 20.09.09, 20:43
  3. Memory Leak in Freehand 10?
    Von Vorototh im Forum Vektor-Programme
    Antworten: 0
    Letzter Beitrag: 23.02.07, 21:07
  4. C++ Memory Leak bei liste
    Von chubbchubb im Forum C/C++
    Antworten: 2
    Letzter Beitrag: 18.11.05, 11:58
  5. [vc] memory leak finden
    Von uhu01 im Forum C/C++
    Antworten: 3
    Letzter Beitrag: 29.03.05, 19:27

Stichworte