Autor Thema: Java OutOfMemoryError  (Gelesen 15691 mal)

Offline birdy

  • Frischling
  • *
  • Beiträge: 37
  • Geschlecht: Weiblich
  • Keep smiling!
Re: Java OutOfMemoryError
« Antwort #20 am: 26.04.05 - 08:55:39 »
Hi Marinero,

danke für die Nachhilfe in ExceptionHandling. Habs eingebaut.

Viel weiter gekommen bin ich bisher leider noch nicht. Gibt es Informationsquellen für Java-Anfänger wie mich, in denen z.B. die Vorgehensweise bei JDBC-Connection beschrieben wird.

Ich hab den Agenten nämlich 1:1 so übernommen und nur geringfügig angepasst, also weiß ich auch nicht wirklich, wie ich es vielleicht besser machen könnte. Auch das mit diesen PreparedStatements würde mich interessieren. Wo kann ich mehr drüber erfahren?

Zu meinem SQL-Statement noch ne Frage. Ich habe meine SQL-Abfrage in 3 Schritten gemacht, d.h. ich krieg 3x nen ResultSet. Liegt hier vielleicht ein Fehler, muss ich jedesmal den ResultSet und das Statement wieder schließen? Ich hab das versucht, allerdings krieg ich dann auch wieder ne Fehlermeldung.

LG, Birgit

Offline birdy

  • Frischling
  • *
  • Beiträge: 37
  • Geschlecht: Weiblich
  • Keep smiling!
Re: Java OutOfMemoryError
« Antwort #21 am: 26.04.05 - 11:26:34 »
Hi,

hab da nochmal ne Frage.

Wäre es ne Möglichkeit, die JDBC-Connection solange aufrecht zu erhalten, bis die DB vom User geschlossen wird?
Also mit 1. Aufruf des Agenten wird die Verbindung aufgebaut und muss dann nicht jedesmal wieder hergestellt werden, wenn mehrmals hintereinander Daten abgerufen werden.

Oder spielt das keine Rolle?

Hab absolut keine Ahnung, was ich noch tun könnte.

Birgit

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #22 am: 26.04.05 - 11:55:53 »
Hallo Birgit.

Zu meinem SQL-Statement noch ne Frage. Ich habe meine SQL-Abfrage in 3 Schritten gemacht, d.h. ich krieg 3x nen ResultSet.
vielleicht kannst du das SQL so optimieren, dass du mit einem Query alle Daten auf einmal bekommst.
Da geht ja mit inner joins, outer joins, subqueries und vieles andere mehr so einiges.
Auch Views und Stored Procedures auf DB-Seite sind zu beachten, wenn es darum geht SQL-Statements einfacher und performanter zu machen. Daneben gibt es noch Temporary Tables, die ich aber z.B. ignoriere. 
Zumindest mit DB2 Version 8 ist der SQL Builder auch nicht ganz schlecht. Damit kann man sich ganz gut komplexere Dinge zusammenklicken und erhält die entsprechende SQL Syntax.   
Du kannst gerne die 3 SQL Statements posten.
Liegt hier vielleicht ein Fehler, muss ich jedesmal den ResultSet und das Statement wieder schließen? Ich hab das versucht, allerdings krieg ich dann auch wieder ne Fehlermeldung.
Sobald du das alte Resultset geschlossen hast, kannst du nicht mehr drauf zugreifen. Du kannst ruhig das alte offenlassen. Das sollte keine große Auswirkung auf die Performance haben. Bin mir nicht ganz sicher, aber ich glaub, dass DB2 JDBC Treiber zumindest ab Version 7 DB2 Resultset und Statement automatisch schliessen, wenn du die Connection schliesst, mit der diese beiden erzeugt worden sind. Das ist zumindest das normale Verhalten von modernen JDBC Treibern. Du mußt auf jeden Fall die Connection schliessen und ZWAR INNERHALB DES AGENTEN, IN DEM DU SIE GEÖFFNET HAST. DAS IST QUASI NATURGESETZ.
1. Kannst du nicht sicher sein, ob der 2. Agent überhaupt läuft (und OFFENE CONNECTIONS SIND BÖSE
2. Ist für die Performance eine lange offene Connection gar nicht gut, besonders wenn mehrere User drauf zugreifen. Man soll die Connection immer nur für möglichst kurze Zeit offen halten und AUF JEDEN FALL IN DER ROUTINE SCHLIESSEN, IN DER SIE AUFGERUFEN WURDE.
Es gibt Fälle, wo es wünschenswert ist, eine Datenbanktransaktion über mehrere UserScreens laufen zu lassen.
Bsp:
Buche Platz in Flugzeug
Gebe Kredikarteninfo
Bezahlen.
Dem User werden nacheinander 3 Seiten geschickt, wo er was anklickt. Auf Datenbankebene wird es aber selbst dort 3 Connections geöffnet und geschlossen (1 pro Screen des Users). Gleiches gilt für Datenbanktransaktionen.
Um das konsistent zu halten, behilft man sich mit Tricks. Am bekanntesten sind optimistic und pessimistic locking.

Offline birdy

  • Frischling
  • *
  • Beiträge: 37
  • Geschlecht: Weiblich
  • Keep smiling!
Re: Java OutOfMemoryError
« Antwort #23 am: 26.04.05 - 12:05:28 »
Schön, dass du wieder da bist. :)

Hab mein SQL-Statement auch schon mittels INNER JOIN auf 1 Query reduziert, aber da kams mir so vor, als würde es noch länger dauern, bis ich ein Ergebnis bekomme.
Nachdem der Fehler so oder so auftritt, bleibe ich jetzt bei meinen 3 Schritten.

Das mit der Connection seh ich ein, greife halt nach jedem Strohhalm.

Werde als nächstes mal die jt400.jar in mein jvm/lib/ext Verzeichnis einbinden. Vielleicht hilft das ja.

Ihr werdet sicherlich wieder von mir hören ;-)

LG, Birgit

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #24 am: 26.04.05 - 12:23:16 »
Prüfe die Indexe in den Tabellen. Für alle Spalten, auf die die Joins gehen, muß es in der Datenbank einen Index geben. Frage den Datenbankadministrator. Falls es einen gibt.
Dies sollte die Performance deutlich verbessern.

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #25 am: 26.04.05 - 12:43:16 »
[kurzer_zwischen_rant]  >:(
In sämtlichen mir bekannten Java Umgebungen ausser Lotus Notes kann man btw sogenannte ConnectionPools benutzen. Da muß man Connections auch schliessen, nur werden sie da an den besagten Pool zurückgegeben.
Das ist seit ca. 2001 Standard.
Mittlerweile gibt es auch alle möglichen caching Lösungen (von sehr einfach--> ich selbst benutz z.B. einfach eine HashMap bis sehr sophisticated und verteilt).
Weder Connection Pools noch diese Caches kann man aus architekturellen Gründen in Domino Agenten benutzen.
Imho sind solche Dinge der rationale Grund, warum Lotus überhaupt mit Workplace angefangen hat.
 

Offline birdy

  • Frischling
  • *
  • Beiträge: 37
  • Geschlecht: Weiblich
  • Keep smiling!
Re: Java OutOfMemoryError
« Antwort #26 am: 26.04.05 - 14:43:45 »
 ;D ;D ;D

Ich kann gar nicht sagen, wie froh ich bin, mein Problem scheint gelöst zu sein.
Habe die beiden jar-Files, die im Agent eingebunden waren, in mein lokales Verzeichnis jvm/lib/ext gepackt und jetzt scheint es zu laufen. Habe den Agenten jetzt bestimmt 20x hintereinander laufen lassen und es kam keine Fehlermeldung!!! Vorher war schon bei 6-7x Ende Gelände.
Und das beste an der Sache, jetzt gehts sogar schneller als vorher!

Ich hab leider etwas gebraucht, bis ich gecheckt hab, was mit diesem Attachment gemeint ist. Nachdem ich den Agenten schon fast fertig bekommen habe, wusste ich nicht, dass da zwei jar.-Dateien anhingen. Aber man lernt ja nie aus.

Also vielen Dank an alle, die sich hier für mich den Kopf zerbrochen haben. Ihr wart mir wirklich ne große Hilfe. Qojote hatte ja bereits zu Beginn geschrieben, wie es geht, ich stand nur sehr auf der Leitung.

So long, machts gut und bis zum nächsten Prob (hoffe nicht allzu bald).

LG, Birgit

Offline qojote

  • Aktives Mitglied
  • ***
  • Beiträge: 229
  • I love YaBB 1G - SP1!
Re: Java OutOfMemoryError
« Antwort #27 am: 27.04.05 - 08:39:14 »
Hi,

schön dass es jetzt geht.
Ich hatte leider die letzten Tage kaum Zeit sonst hätte ich mein Posting nochmal vertieft.
Aber Marinero hat ja wie immer sehr gute Hilfestellung geleistet.

Gruß
Qojote

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #28 am: 27.04.05 - 10:09:18 »
Bleibt noch die Frage wie du die db2libs verteilst.
Java Client Umgebungen wie Java Web Start und Eclipse RCP verfügen über Elemente, die das automatisch machen. Neuinstallation, Check ob neues Release, automatischer Download von neuem Release.
Vielleicht kennt der Administrator ja eine Möglichkeit, um das automatisch mit Windowsmitteln zu verteilen.

Offline birdy

  • Frischling
  • *
  • Beiträge: 37
  • Geschlecht: Weiblich
  • Keep smiling!
Re: Java OutOfMemoryError
« Antwort #29 am: 27.04.05 - 10:56:02 »
Hallo zusammen,

ich schon wieder. Hab mich wohl zu früh gefreut.
Das mit den lokalen jar.-Dateien funktioniert nur bei den Windows2000-Rechnern. Haben aber auch Windows XP im Einsatz und da läufts nicht.

Könnt langsam durchdrehen. Folgendes steht in der Java-Debug-Konsole:

java.lang.ClassNotFoundException: com.ibm.as400.access.AS400JDBCDriver
   at lotus.domino.AgentLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:448)
   at java.lang.Class.forName1(Native Method)
   at java.lang.Class.forName(Class.java:142)
   at JavaAgent.NotesMain(JavaAgent.java:52)
   at lotus.domino.AgentBase.runNotes(Unknown Source)
   at lotus.domino.NotesThread.run(NotesThread.java:215)

Hat jemand ne Idee, was ich jetz machen kann???

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #30 am: 27.04.05 - 11:40:23 »
Versuch mal den Notes Client auf WinXP herunterzufahren und neu zu starten. Es kann daran liegen.

Gruß Axel

Offline qojote

  • Aktives Mitglied
  • ***
  • Beiträge: 229
  • I love YaBB 1G - SP1!
Re: Java OutOfMemoryError
« Antwort #31 am: 27.04.05 - 12:23:34 »
Hi,

du kannst alternativ den Pfad zu den Dateien in der Notes.ini
unter JavaUserClases="c:\xxx" eintragen.
Hat den Vorteil das du den Pfad selbst bestimmen kannst.

So hab ich das an meinem Client gemacht das mit dem ext Verzeichnis hab ich nur am Server genutzt.

Gruß
Qojote

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #32 am: 27.04.05 - 12:39:16 »
... das geht auch. Versuch aber bitte erstmal den Notes-Client runter- und hochzufahren. Oder am besten das ganze XP.
Falls der im Windows XP nicht das ext Verzeichnis finden würde, wäre das sehr - im Sinne von völlig - ich glaubs nicht - merkwürdig.
Das der Client noch mal hoch- und runtergefahren werden muß, ist normal.

Offline birdy

  • Frischling
  • *
  • Beiträge: 37
  • Geschlecht: Weiblich
  • Keep smiling!
Re: Java OutOfMemoryError
« Antwort #33 am: 27.04.05 - 13:03:03 »
Hi Ralf,

will ja noch nix verschreien, aber scheint zu funktionieren.
Habs jetz an 2 Rechnern probiert mit dem Neustart und hat geklappt.

Danke für den Tipp, hätt ich ja mal wieder aus selbst drauf kommen können.

Hab grad schon ein Glas Sekt auf euch getrunken in meiner Mittagspause ;o)

LG, Birgit

Offline birdy

  • Frischling
  • *
  • Beiträge: 37
  • Geschlecht: Weiblich
  • Keep smiling!
Re: Java OutOfMemoryError
« Antwort #34 am: 27.04.05 - 13:04:21 »
Ups, vertippt, bist ja der Marinero. Sorry
Sekt schon zur Mittagszeit bekommt mir wohl nicht.

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #35 am: 28.04.05 - 00:07:59 »
Glückwunsch
Ich mach ja momentan das umgekehrte.
Ich will aus Performancegründen RDBMS-Hits vermeiden und statt dessen mit einem cache kommunizieren.
Könnte ich ja auch pro gesparten Select gegen RDBMS eine Flasche Sekt trinken.
Diese Woche wäre ich bislang stocknüchtern geblieben (mach das aber nur abends).
« Letzte Änderung: 28.04.05 - 07:26:42 von Marinero Atlántico »

Offline Teletambi

  • Junior Mitglied
  • **
  • Beiträge: 63
  • Ich liebe dieses Forum!
Re: Java OutOfMemoryError
« Antwort #36 am: 04.06.05 - 04:07:22 »
Hallo,

hast du vlt. schon einmal versucht deinen JavaCode in einem "ordentlichen" try-catch-finally Block unterzubringen und mehrere Execptions (NotesException, SQLException sowie Exception) in einem jeweils separaten catch unterzubringen? Die Aufrufe für resSet.close(), stmt.close() etc. gehören dann in das abschließende finally.
Da diese wiederum eine Exception werfen können, müssen diese auch in einem try-catch Block enthalten sein.

Ich hatte ein ähnliches Problem mit der JDBC-Programmierung und konnte anfangs keine Ursache dafür finden bis ich alle möglich Exceptions mit  der entsprechende Fehlermeldungausgabe behandelt habe.

Ich nehme mal ganz stark an, dass irgendwo eine Exception auftritt, welche du in deinem Code nicht behandelt hast.

MfG Teletambi

Marinero Atlántico

  • Gast
Re: Java OutOfMemoryError
« Antwort #37 am: 04.06.05 - 11:22:08 »
@Teletambi: Dieser Thread war bereits als gelöst gemeldet.
Trotzdem weisst du auf eine sehr wichtige Sache hin.
Ist mir damals entgangen, wobei ich mich in dem Punkt "external Ressourcen schliessen" bisher für paranoid gehalten habe.

Schliessen der Connection im finally (oder meine traditionelle Lösung s.u.) finde ich auch besser, weiss nicht, warum ich damals nicht darauf hingewiesen habe. Das wurde hier am Ende des try und im catch Block geschlossen, was nicht perfekt ist, hier aber offenbar ausreichend.
Danke aber für deinen Hinweis, weil du in gewissen Punkten sicher recht hast.

Jede Exception *einzeln* zu catchen halte ich hingegen für unnötig.
Schliesslich haben Exceptions in Java eine gewisse Vererbungshierarchie, die man sich zu Nutze machen kann.
Wenn du eine gewisse Menge an Funktionalität/per Stunde programmierst, hat man in der Praxis keine Zeit, jede Exception einzeln zu catchen. Statt dessen sollte man sich Gedanken machen, wo spezifisches Exception Handling Sinn macht. Wo nicht, sollte man die Superklassen verwenden (s.u.)

In Java gibt es 2 Arten von Exceptions.
Checked und Unchecked.
Die Checked sind die, wo der Compiler immer anmeckert, dass man diese Exception abfangen muss. Alle checked Exceptions erben von der Klasse java.lang.Exception.
Unchecked Exceptions müssen nach Meinung des Compilers dagegen nicht per catch abgefangen werden. Das sind oft exception, die mit dem Wissen des Compilers eigentlich immer auftreten können. Z.B. NullPointerException. Der Compiler weiss nicht, ob später bei der Ausführung des Programms eine Referenz auf ein Objekt weist oder nicht.
 
Um sicher zu gehen, dass ein catch-Block für alle Arten von Exceptions zuständig ist, kann man java.lang.Throwable nutzen.  Throwable ist die Superklasse von Exception, RuntimeException und Error ist (wobei RuntimeException und Error Superklassen aller unchecked Exceptions sind).

Wenn man z.B. mit externen Ressourcen arbeitet, kann es imho Sinn machen mit Throwable zu arbeiten. Oder man schliesst sie eben im finally.
Über dem Throwable können dann spezifischere Exceptions abgefangen werden.

z.B.:
Code
try {
...
} catch (NotesException e) {
... do stuff ..
}
catch (SQLException e) {
... do stuff ..
}
catch (Throwable t) {
/* würde man hier, in allen darüberliegenden catches und im try die Connections schliessen wäre das safe. Man kann hierfür eine extra Methode vorsehen. So mach ich das immer aus Gewohnheit. */
... do stuff ...
} finally {
/* würde man hier die Connections schliessen und im try nicht wäre das auch safe und weniger Tipparbeit. Vielleicht sollte ich meine Gewohnheit ändern. Wobei ich für DB-Zugriff Frameworks (s.u.) nutze, wo ich kann: Heisst überall ausser in Java in Notes. */
}

In der Tat ist gerade das Exception-Handling und auch Probleme mit stalled Connections (die man in den Griff kriegen kann) Punkte, die oft an der Architektur von JDBC kritisiert worden sind.
Dies ist ein eher unwichtiger Grund, warum die Leute so gerne Frameworks wie Hibernate oder ibatis SQLMaps statt low-level JDBC arbeiten, da diese Frameworks diese und andere Probleme schon gelöst haben. 

Ach ja. Und bei OutOfMemoryError extends java.lang.Error wird natürlich weder das catch noch das finally aufgerufen.  ;D

Gruß Axel
« Letzte Änderung: 04.06.05 - 12:59:08 von Marinero Atlántico »

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz