EDIT: The problem raised by this question is very well explained and confirmed in this article by codebulb.ch, including some comparison between JSF @ViewScoped
, CDI @ViewSCoped
, and the Omnifaces @ViewScoped
, and a clear statement that JSF @ViewScoped
is 'leaky by design': May 24, 2015 Java EE 7 Bean scopes compared part 2 of 2
EDIT: 2017-12-05 The test case used for this question is still extremely useful, however the conclusions concerning Garbage Collection in the original post (and images) were based on JVisualVM, and I have since found they are not valid. Use the NetBeans Profiler instead ! I am now getting completely consistent results for OmniFaces ViewScoped with the test app on forcing GC from within the NetBeans Profiler instead of JVisualVM attached to GlassFish/Payara, where I am getting references still held (even after @PreDestroy called) by field sessionListeners
of type com.sun.web.server.WebContainerListener
within ContainerBase$ContainerBackgroundProcessor
, and they won't GC.
It is known that in JSF2.2, for a page that uses a @ViewScoped bean, navigating away from it (or reloading it) using any of the following techniques will result in instances of the @ViewScoped bean "dangling" in the session so that it will not be garbage collected, leading to endlessly growing heap memory (as long as provoked by GETs):
Using an h:link to GET a new page.
Using an h:outputLink (or an HTML A tag) to GET a new page.
Reloading the page in the browser using a RELOAD command or button.
Reloading the page using a keyboard ENTER on the browser URL (also a GET).
By contrast, passing through the JSF navigation system by using say an h:commandButton results in the release of the @ViewScoped bean such that it can be garbage collected.
This is explained (by BalusC) at JSF 2.1 ViewScopedBean @PreDestroy method is not called and demonstrated for JSF2.2 and Mojarra 2.2.9 by my small NetBeans example project at https://mcmap.net/q/17960/-jsf-2-1-viewscopedbean-predestroy-method-is-not-called, which project illustrates the various navigation cases and is available for download here. (EDIT: 2015-05-28: The full code is now also available here below.)
[EDIT: 2016-11-13 There is now also an improved test web app with full instructions and comparison with OmniFaces @ViewScoped
and result table on GitHub here: https://github.com/webelcomau/JSFviewScopedNav]
I repeat here an image of the index.html, which summarises the navigation cases and the results for heap memory:
Q: How can I detect such "hanging/dangling" @ViewScoped beans caused by GET navigations and remove them, or otherwise render them garbage collectable ?
Please note that I am not asking how to clean them up when the session ends, I have already seen various solutions for that, I am looking for ways to clean them up during a session, so that heap memory does not grow excessively during a session due to inadvertent GET navigations.
window.onbeforeunload
. I have this in mind for OmniFaces 2.2@ViewScoped
. – Neutralize@ViewScoped
bean forms with OmniFaces 2.5.1 here github.com/webelcomau/JSFviewScopedNav, and related OmniFaces-specific question with results tables: JSF: Mojarra vs. OmniFaces @ViewScoped: @PreDestroy called but bean can't be garbage collected – Tribromoethanol