# [Hibernate] Geschwindigkeitseinbußen bis hin zum Programmabsturz



## casi91 (14. Mai 2012)

Hallo Community,
ich arbeite mal wieder weiter mit Hibernate und mir wurde ein Problem beschrieben, bei dem ich derzeit nicht weiß wie und auf was ich testen muss. (Kann auch sein, dass es garnicht an Hibernate liegt, ist aber mein Verdacht)

Problembeschreiben meines Kollegen:
Nach mehreren Speichervorgängen, dauert der vorgang von mal zu mal länger. Ab einem bestimmten Zeitpunkt reagiert das Programm garnicht mehr.

Dies ist natürlich bei einem Programm das viele Speichervorgänge hat schlecht.
Hat vielleicht schonmal jemand erfahrungen mit einem derartigen Problem gehabt?
Wie erwähnt, habe ich derzeit keine Ahnung, wie ich es am besten teste um herauszufinden, warum das passiert.

Danke schonmal im vorraus


----------



## Marcinek (14. Mai 2012)

Wie soll man den bei dieser Problembeschreibung den auf Hibernate schließen und vor allem, wie sollen wir nun hier helfen??

Das ist ja pures raten hier.

Profiler anschmeißen und go.


----------



## casi91 (14. Mai 2012)

Das die Beschreibung äußerst dürftig ist, ist mir auch bewusst.
Tut mir auch leid, aber besser geht es derzeit nicht.
Und auf Hibernate habe ich einfach nur geschlossen, da es bei den Speicheroperationen passiert.
(Ist natürlich aber eine sehr wage Vermutung)

Auf die gefahr hin, dass ich mich nun lächerlich mache.
Aber was meinst du mit Profiler?
(ich merke gerade es gibt noch sehr sehr sehr viel, was ich lernen muss ^.^)

UPDATE
Hab mir gerade angeschaut was du mit Profiler gemeint hast.
Entschuldige die dumme Frage.
Da es aber recht viele gibt, welcher ist deiner Meinung nach gut.
Wie steht es mit dem eclipse-Plugin "Hyades"?


----------



## Marcinek (14. Mai 2012)

Ich benutze immer den, der eim jdk dabei ist.


----------



## casi91 (14. Mai 2012)

wie verwende ich den?
hab nach kurzer suche noch keine Anleitung gefunden, die mir geholen hätte.
(benutze eclipse)


----------



## Marcinek (14. Mai 2012)

Du startest dein Programm und den Profiler.

Dann kann der Profiler sich an die JVM hängen und die Inhalte anzeigen.

Wie das geht steht überall im Netz.


----------



## ARadauer (14. Mai 2012)

macht ihr viele inserts? ich würd einfach zwischen durch mal die session clearen...


----------



## KSG9|sebastian (14. Mai 2012)

Hi,

erstmal von vorne.

Was genau für eine Anwendung ist das:

1) Webanwendung (GWT, JSF oder ?)
2) Fatclient (Swing, RCP, ??)

Falls Fatclient:

Am einfachsten mal mit JConsole draufschauen:

1. Anwendungs starten
2. JConsole starten
3. Mit JConsole auf die Anwendung aufschalten (selbsterklärend)
4. Anwendungs klicken und mal JConsole beobachten
5. Sobald die Anwendungs abschmiert in JConsole schauen was passiert ist
(6). Falls Hibernate die Session flushen (google benutzen) und an ensprechenden Stellen clearen. Macht ihr Bulk-Operationen mit Hibernate?

Ich tipp mal drauf, dass der GarbageCollector seinen Dienst nicht tun kann weil Resourcen nicht geschlossen, Objekte nicht dereferenziert o.ä. werden.


----------



## casi91 (14. Mai 2012)

Erst mal danke für die Antworten 
Nur wie zuzvor schon erwähnt merke ich, dass ich viele Sachen noch nicht weiß ^.^

Ich habe nun Pause und werde mich danach mal mit der JConsole beschäftigen (noch nie genutzt)
Und was "Bulk-Operationen" sind weiß ich auch nicht.

sorry.


----------



## casi91 (14. Mai 2012)

So, da bin ich wieder.
Ich habe die jConsole nun gestartet und ein wenig rumgeklickt.
Noch ist nichts abgestürzt, aber leider weiß ich auch nicht so ganz, wie ich die Anzeige lesen muss.
(Sprich was sind gute Werte, was sind schlechte Werte usw.)

Und nun zu dem "flushen" und "clearen"

meine Speichermethoden sehen in der Regel so aus:

```
session.saveOrUpdate(object);
session.flush();
session.close();
```


was sind deiner Ansicht nach gute Stellen zum "clearen"?

Es kann jetzt gut sein, dass ich das falsch im Kopf habe bzw. unseren Professor falsch verstanden habe, aber sollte das dereferenzieren o.ä. nicht unnötig sein und der GC erkennt selbst, was aufgeräumt werden darf/kann?
Oder verwechsle ich hier ein paar Dinge?


----------



## Marcinek (14. Mai 2012)

Wir haben hier nix, wie wir dir helfen können.

Zu solchen zeitlichen Verzögerungen kann es aus vielen Gründen kommen. U.a. wenn Objekte eben im Speicher verbleiben und man jedermal über diese Iterieren muss. Beim nächsten Speichern hast du doppelt so viele und so weiter.

Iwann wird es eben langsam.

Zu beachten wäre es, ob solche relevanten Objekte da bleiben. Der GC räumt nur nicht referenzierte Objekte weg.

Hier kann man endsprechende Lektüren begnügen.

Weiterhin wäre es für die Lösungsfindung nicht schlecht die o.g. Fragen von sebastian zu beantworten.

s


----------



## casi91 (14. Mai 2012)

Das der GC nur unreferenzierte Objekte weg nimmt ist mir bewusst.
Gibt es Möglichkeiten festzustellen, ob irgendwo noch referenzierte Objekte bestehen, die aber nicht mehr gebraucht werden? 

und zu den Fragen
1. Es ist eine Swing-Anwendung, also ein "Fatclient"
2. Ich weiß leider nicht was Bulk-Operationen sind


tut mir leid das ich keine genaueren Informationen bieten kann :-(
Wäre auch glücklicher, wenn ich das tun könnte.


----------



## Marcinek (14. Mai 2012)

Der Profiler listet dir alle Instanzen von allen Objekten auf.

Du musst dich schon damit beschäftigen. Das geht nicht "Starten ohh ja da ist mein Speicherleck".

Das hängt sehr stark von deinem Code und dem gewünschten verhalten ab.

Wenn ich ein Wort nicht kenne, dann google ich danach.


----------



## maki (14. Mai 2012)

*verschoben*

Hast du denn niemanden in der Firma der dir helfen könnte?

Sorry, aber so wird das doch nix, weisst weder ob noch wo es ein Speicherleck gibt, anstatt hibernate hättest du auch String oder Banane schreiben können, nimmt sich nix an Info Gehalt bzw. dem fehlen dessen.

Zum Thema Profiler:
VisualVm wird ausgeliefert mit dem JDK, JConsole ist veraltet.


----------



## casi91 (14. Mai 2012)

Leider nein.
Das meine Ausführung und Beschreibung nicht gut ist, weil ich den Fehler nicht korrekt Beschreiben kann ist mir auch klar. (Hab ich mich ja schon mehrmals entschuldigt)

Und google ist bei mir am rundlaufen, weil ich Sachen nachlese. Dachte mir nur, dass es nicht schaden kann das ich hier nochmal schreibe, dass ich derzeit keine Ahnung habe was es ist. Wenn dies der Falsche Weg ist, entschuldige ich mich dafür.

Zum Thema Profiler:
Dann beschäftige ich mich mal mit VisualVm, vielleicht bringt dies dann ein wenig Licht ins dunkel 

Ich bedanke mich bei allen, die bisher was geschrieben haben.
Sollte ich irgendwann mal schlauer sein (was ich doch hoffe), schreib ich natürlich auch hier rein, was es den letzten Endes war.
Sollte in der Zeit noch irgendjemand aus meiner dürftigen Beschreibung was herauslesen können, freue ich mich natürlich über jeden neuen Kommentar.


----------



## casi91 (14. Mai 2012)

So, ich habe nun VisualVM mal gestartet.
Und mir fiel direkt etwas auf.
Und zwar Finde ich sehr oft den Thread: "AS400 Read Daemon-x" (x steht hierbei für eine Zahl von 1 bis n)
Hierbei kommt bei jeder neuen DB Abfrage ein oder auch zwei solcher Threads dabei.
(Könnte dies schon ein Teil der Lösung sein? Weil nach einer halben Stunde von Speicher und Lade-Methoden werden dann entsprechend viele Threads vorhanden sein?)

Ich bin derweil schon am suchen, wie ich diese Threads beenden kann, hab aber noch nicht den zündenden Hinweis gefunden. 
Ich habe nur gelesen, dass jemand schonmal das Problem hatte und es daran gelegen hat, dass er die Connection nicht geschlossen hat.

Hatte hier vielleicht schonmal jemand etwas mit diesen Threads zu tun?
(wie erwähnt bin ich bereits am googlen, ich wollte einfach nur mal nachfragen, also bitte nicht denken "dann google doch" ;-) )


----------



## maki (14. Mai 2012)

Wie groß wird n denn mit der Zeit?
Wieviele Connections hält dein ConnectionPool denn vor?


----------



## casi91 (14. Mai 2012)

Also in meinem kurzen Test (ca 10 Minuten)
Kam ich schon auf x=20.
Längere Tests werde ich nun in den nächsten Tagen machen. Ich könnte mir vorstellen, dass x noch deutlich weiter steigt.
Die Frage mit dem ConnectionPool kann ich dir derzeit nicht beantworten.
Ich werde zusehen, dass ich das bis Morgen herausbekomme und werde es dann schreiben


----------



## casi91 (15. Mai 2012)

Guten Morgen,
hier noch die Antwort zu dem Connectionpool (hoffe du meinst auch diese Einstellung)

```
<property name="hibernate.connection.pool_size">1</property>
```


----------



## casi91 (15. Mai 2012)

omg -.-"
Schande über mein Haupt...
Ich habe gerade 2 Stellen in meinem Quellcode gefunden, die ich nicht verbessert hatte...
Kurz zur Erläuterung: 
als ich angefangen hatte mit Hibernate etc. hatte ich mehrere SessionFactorys erzeugt, anstatt nur neue Sessions. Im laufe meiner Einarbeitung hab ich dann aber gelesen, dass man ja nur eine SessionFactory haben sollte (außer man verwendet verschiedene Datenbanken).
Also habe ich mir eine Singleton-Klasse geschrieben, die mit meiner DB kommuniziert und einmalig eine SessionFactory anlegt und von dieser entsprechend die Sessions generiert.
Nun habe ich 2 Zeilen gefunden (die relativ oft aufgerufen werden) bei denen ich noch "alten" Code stehen hatte...sprich an diesen Stellen habe ich immer wieder neue SessionFactorys erzeugt und nie geschlossen. Daher kamen dann logischerweise diese vielen Threads.
(oder sehen ich das falsch?)

Könnte das auch das Problem gewesen sein, weshalb sich das Programm irgendwann aufgehängt hat?


----------

