# org.hibernate.impl.SessionFactoryImpl Memory Leak



## Tho82 (19. Apr 2011)

Hallo Zusammen,

wir verwenden bei uns in einer Applikation Hibernate. Die Session wird beim Startup aufgemacht und bleibt offen, solange die Applikation lebt. Der Speicher steigt mit der Zeit immer mehr an, Eclipse Memory Analizer sagt, dies ist ein potentielles Memory Leak:

One instance of "org.hibernate.impl.SessionFactoryImpl" loaded by.... allokiert 11MB Speicher


In der Tat steigt die Größe mehr und mehr an.

Woran liegt das? Wird da etwas gecached? Falls ja, gibt es eine Möglichkeit, das was hängen bleibt zu bereinigen ohne die Session wieder zu schließen?

Vielen Dank und viele Grüße,
Tho


----------



## SlaterB (19. Apr 2011)

vielleicht hilft
http://www.java-forum.org/datenbank...sion-factory-speicherung-queries-results.html


----------



## maki (19. Apr 2011)

> Woran liegt das? Wird da etwas gecached? Falls ja, gibt es eine Möglichkeit, das was hängen bleibt zu bereinigen ohne die Session wieder zu schließen?


Das liegt daran dass du die Session die ganze Zeit offen lässt.



> Falls ja, gibt es eine Möglichkeit, das was hängen bleibt zu bereinigen ohne die Session wieder zu schließen?


Die offene Session ist das Problem, nicht die Lösung, dein Memory Leak hast du selber verursacht.

Schliesse die Session sobald wie möglich und versuche sie nicht ständig offen zu halten.


----------



## Tho82 (19. Apr 2011)

maki hat gesagt.:


> Das liegt daran dass du die Session die ganze Zeit offen lässt.
> 
> 
> Die offene Session ist das Problem, nicht die Lösung, dein Memory Leak hast du selber verursacht.
> ...



Das Problem ist, dass das im Moment nicht gemacht werden kann. Die offene Session ist quasi vorgegeben.


----------



## maki (19. Apr 2011)

Dann ist das Memory Leak auch vorgegeben.
Typischer Designfehler den man nicht mal eben korrigieren kann ohne das Design bzw. die Architektur zu korrigieren.


----------



## SlaterB (19. Apr 2011)

warum muss denn eine Session ein umunstößliches MemoryLeak sein, solange offen, ist das nicht zu engstirnig?
je nach Verwendung muss eine Session nicht mehr als eine Connection sein,

wenn irgendwelche Daten, ob Queries oder Objekte oder sonstige Zustandsinformationen gecacht und evtl. nicht gelöscht werden, 
dann ist das doch keine Naturkonstante, sondern nur Pech/ Suche nach den richtigen Einstellungen?


----------



## maki (19. Apr 2011)

Eine Session ist kein Memory Leak, aber nur eine einzige Sesssion zu haben und diese dann für die gesamte Laufzeit der App offen zu halten ist...  (suche nach einem substitut für "ignorant" das nicht beleidigend ist)

Die Grundregel lautet eine Session nur solange wie nötig offenzuhalten, und das sollte eben so kurz wie möglich sein.
Ressourcen werden belegt aber wohl nicht genutzt, die Session wird immer fetter, ist wohl gewollt sonst würde man das so nicht machen? -> Sabotage 

Das hat nix mit Pech zu tun oder der Suche nach irgendwelchen Einstellungen, sondern zeigt das Grundregeln ignoriert wurden, das rächt sich immer.

Ist übrigens nicht nur bei Hibernate so, sondern bei ORM im allgemeinen, also doch sowas wie ein "Naturgesetz".


----------



## Tho82 (19. Apr 2011)

maki hat gesagt.:


> Eine Session ist kein Memory Leak, aber nur eine einzige Sesssion zu haben und diese dann für die gesamte Laufzeit der App offen zu halten ist...  (suche nach einem substitut für "ignorant" das nicht beleidigend ist)
> 
> Die Grundregel lautet eine Session nur solange wie nötig offenzuhalten, und das sollte eben so kurz wie möglich sein.
> Ressourcen werden belegt aber wohl nicht genutzt, die Session wird immer fetter, ist wohl gewollt sonst würde man das so nicht machen? -> Sabotage
> ...




Ich gebe dir an der Stelle recht. Das ist ein Designfehler, aber einer, mit dem ich in dieser Version der Software leben muss für die ich das Memory Leak in den Griff bekommen sollte. In neueren Versionen wurde auf kurze Sessions bereits umgestellt. Die Frage ist, ob man das trotz der langen Sessions überhaupt in den Griff bekommen kann?


----------



## maki (19. Apr 2011)

> Die Frage ist, ob man das trotz der langen Sessions überhaupt in den Griff bekommen kann?


Wie gesagt, die "lange Session" ist das Problem, ist sowas wie ein Cache, alle Entities die mal "angefasst" wurden werden dort gehalten, irgendwann hat man eben die komplette Datenbank als Entities im RAM und noch ein bisschen mehr 

Ansosnten fallen mir nur die üblichen Optimierungen ein, nebenbei gefragt, habt ihr auch alle Relationen auf Eager Fetching umgestellt, ist nämlich auch so ein Kardinalsfehler, es gibt einen Grund warum diese per default als Lazy fetched konfiguriert sind.


----------



## Tho82 (19. Apr 2011)

maki hat gesagt.:


> Wie gesagt, die "lange Session" ist das Problem, ist sowas wie ein Cache, alle Entities die mal "angefasst" wurden werden dort gehalten, irgendwann hat man eben die komplette Datenbank als Entities im RAM und noch ein bisschen mehr
> 
> Ansosnten fallen mir nur die üblichen Optimierungen ein, nebenbei gefragt, habt ihr auch alle Relationen auf Eager Fetching umgestellt, ist nämlich auch so ein Kardinalsfehler, es gibt einen Grund warum diese per default als Lazy fetched konfiguriert sind.




Okay, aber wenn ich session.setCacheMode(CacheMode.IGNORE);  mache, dann dürfte das doch genau nichtmehr passieren oder liege ich falsch?

Die Relationen sind auf Lazy eingestellt.


----------



## maki (19. Apr 2011)

Damit konfigurierst du den 2nd Level Cache.
Die Session ist der sog. 1st Level Cache.

Schon mal mit einem flush() versucht? Geht das?
Ist ein anderes Hibernate/ORM "Antipattern", Feuer mit Feuer bekämpfen erzeugt viel Rauch, aber vielleicht ist es ja das kleinere übel.


----------

