Ich bin auf Probleme gestoßen, um sicherzustellen, dass ein Spring-Anwendungskontext, den ich zerstöre, komplett verschwunden ist, und kann nicht sehen, dass das Objekt Müll gesammelt wird. Wenn ich mir die Instanz in VisualVM anschaue, sehe ich, dass es eine Reihe von ausstehenden Verweisen sowohl auf den Kontext als auch auf die Bean-Factory gibt, die bestehen bleiben, sobald der Kontext geschlossen und zerstört wird. Dies alles im Zusammenhang mit der anfänglichen Einrichtung der Bean-Factory (während der Refresh-Methode von AbstractApplicationContext), die die Bean-Factory und den Kontext mit verschiedenen Bean-Post-Prozessoren usw. registriert.
Es scheint keine Methoden in der Bean-Factory oder in den Anwendungskontexten zu geben (auch nicht in den aktualisierbaren), die mehr als nur den Verweis der untersten Ebene auf die Bean-Factory entfernen. Das Ergebnis ist, dass es scheint, Speicher zu verlieren und unter bestimmten Umständen die saubere Neu-Erstellung eines Kontexts zu verhindern.
Ich frage, wie die Software, an der ich gerade arbeite, den Kontext dynamisch erstellen / zerstören und dann neu erstellen kann (da Module dynamisch geladen und entladen werden) und die übrig gebliebenen Elemente des Kontexts und der Bean-Factory Probleme verursachen mit Komponenten wie spring-data-jpa (insbesondere der Proxy, der die Repository-Schnittstellen an die Repository-Implementierungen bindet).
Kennt jemand eine Möglichkeit, einen Kontext und eine Bean-Factory sauber und vollständig zu entfernen, ohne die VM, die sie ursprünglich erstellt hat, vollständig zu schließen?
Nachdem ich das kürzlich noch einmal angeschaut habe, habe ich bemerkt, dass ich die doClose()
-Methode des Kontexts außer Kraft setzte, um sicherzustellen, dass die Beans vollständig zerstört wurden, aber nicht die super.doClose()
-Methode aufgerufen hat, was LiveBeansView.unregisterApplicationContext()
/% bedeutete co_de% / destroyBeans()
und getLifecycleProcessor().onClose()
wurden nicht aufgerufen.
Ich habe das hinzugefügt, und (meistens) wenn nicht alle Kontexte jetzt sauber zerstört und Müll gesammelt werden. Ich gehe davon aus, dass alle ausstehenden Kontexte, die nicht zerstört werden, wahrscheinlicher Probleme in unserem eigenen Code sind, mit fehlenden Referenzen.
Wenn Sie den IoC-Container von Spring in einer nicht webbasierten Anwendungsumgebung verwenden; zum Beispiel in einer Rich-Client-Desktop-Umgebung; Sie registrieren einen Shutdown-Hook mit der JVM. Dies stellt ein ordnungsgemäßes Herunterfahren sicher und ruft die relevanten destroy-Methoden auf Ihren Singleton-Beans auf, so dass alle Ressourcen freigegeben werden. Natürlich müssen Sie diese Destroy Callbacks trotzdem konfigurieren und implementieren.
Um einen Shutdown-Hook zu registrieren, sollten Sie die Methode registerShutdownHook()
aufrufen, die in der Klasse AbstractApplicationContext
deklariert ist:
Code
%Vor%Tags und Links java spring-data-jpa spring spring-bean