JSF:Mojarra vs. OmniFaces @ViewScoped:@PreDestroy被调用但是bean不能被垃圾收集

时间:2016-11-13 02:33:24

标签: jsf jsf-2.2 omnifaces mojarra view-scope

这个问题特定于OmniFaces @ViewScoped bean(但是对于使用JSF @ViewScoped更广泛地讨论内存泄漏和资源处理感兴趣)。它基于GitHub上提供的NetBeans8.1测试Web应用程序的结果:

Investigation of undesirable holding of references to various forms of JSF @ViewScoped beans by navigation type

https://github.com/webelcomau/JSFviewScopedNav

该测试Web应用程序有一个全面的自述文件,包含完整的说明,以及带有注释的测试网页,比较过时的JSF2.0风格@ManagedBean @ViewScoped,JSF2.2风格的CDI友好@Named @ViewScoped,以及OmniFaces @Named @ViewScoped bean。

使用JVisualVM进行诊断的结果总结在可下载的电子表格中(另请参见下面的屏幕截图),并指出虽然OmniFaces-2.5.1 @ViewScoped bean在离开时在基于GET的导航情况下调用@PreDestroy方法一个视图(提供释放大多数资源的机会),它似乎不允许实际bean的垃圾收集(至少不使用当前的上下文参数设置)。

在web.xml中,应用程序设置为使用:

com.sun.faces.numberOfViewsInSession 4

com.sun.faces.numberOfLogicalViews 4

默认情况下,此OmniFaces特定参数已注释掉:

org.omnifaces.VIEW_SCOPE_MANAGER_MAX_ACTIVE_VIEW_SCOPES

javax.faces.STATE_SAVING_METHOD默认为'server'。

主要问题是:

Q1:这些OmniFaces @ViewScoped bean无法通过设计进行“实时”垃圾收集(这意味着通过使用Profiler的垃圾收集操作进行挑衅,而不是等到会话结束)这是正确的吗?< / p> 第二季度:如果是这样的话,怎样(应该)最好强制释放它们导航离开页面(特别是在GET导航下)?

问题3:如果不是这样(如果由于某些其他设置导致我的结果不正确)为什么我没有目睹他们挑起垃圾收集,我该怎样做以确保它们确实自动释放?

由于测试网络应用程序是可下载的,文档齐全且希望不言自明,我不会在这里给出代码,只是到目前为止的比较结果,以及测试网页应用程序页面的截图:

screenshots of comparitive results

screenshot of home page leading to per-bean type test cases

screenshot of JSF2.0-style case

screenshot of JSF2.2-style case

screenshot of OmniFaces case

sreenshot of post-navigation target page

1 个答案:

答案 0 :(得分:2)

此问题的原因似乎是由于JVisualVM连接到Glassfish / Payara时的奇怪行为。

test case used for this question仍然非常有用,但原始帖子(和图像)中关于垃圾收集的结论是基于JVisualVM,我发现它们无效。

改用NetBeans Profiler!

我现在可以使用测试应用程序在NetBeans Profiler中强制GC(每个打开的选项卡中有1个omnifaces视图范围的bean),从而获得OmniFaces ViewScoped的完全一致的结果。

当使用附加到GlassFish / Payara的JVisualVM时,sessionListeners内的com.sun.web.server.WebContainerListener字段ContainerBase$ContainerBackgroundProcessor仍然保留了引用(即使在@PreDestroy调用之后),但它们不会GC

该图显示了附加到Payara的JVisualVM的屏幕截图,只打开了一个标签但仍保留了9个OmniViewBean实例,无论GC被强制使用多长时间。

Screenshot of JVisualVM attached to Payara with only 1 tab open but 9 OmniViewBean instances held

使用Mojarra-2.3.0与NetBeans IDE 8.2 Profiler中的OmniFaces-2.6.6更新结果表

Updated results table using Mojarra-2.3.0 vs OmniFaces-2.6.6 in NetBeans IDE 8.2 Profiler

更新了test app序列:

home

JSF2.0 @ManagedBean @ViewScoped

JSF2.3 @Named @ViewScoped

OmniFaces 2.6.6 @ViewScoped with @Named