Jsf 2 JSF2@viewscope bean从未被销毁

Jsf 2 JSF2@viewscope bean从未被销毁,jsf-2,memory-leaks,mojarra,Jsf 2,Memory Leaks,Mojarra,我已经花了3天时间寻找可能的解决方法,所以我的ViewScoped bean不会导致OutOfMemoryException,但没有任何运气 首先,我的环境: JBoss AS 7.1.1.1最终版本 莫哈拉2.1.7 我认为ViewScope bean会在会话到期时被销毁,但它们不会被销毁(通过堆转储检查)。我在Mojarra 2.1.16中发现了以下新功能,解决了此问题,但遗憾的是,目前无法升级到此版本: 此问题还与以下线程有关: 当会话结束(注销或会话过期)时,我能做些什么来删除所有创

我已经花了3天时间寻找可能的解决方法,所以我的ViewScoped bean不会导致OutOfMemoryException,但没有任何运气

首先,我的环境: JBoss AS 7.1.1.1最终版本 莫哈拉2.1.7

我认为ViewScope bean会在会话到期时被销毁,但它们不会被销毁(通过堆转储检查)。我在Mojarra 2.1.16中发现了以下新功能,解决了此问题,但遗憾的是,目前无法升级到此版本:

此问题还与以下线程有关:

当会话结束(注销或会话过期)时,我能做些什么来删除所有创建的ViewScope bean吗?在SessionScoped bean中保存viewMap并调用clear()也不会破坏这些bean

提前感谢,


Daniel

为了解决这个bug,我将代码剥离到以下部分:

一个非常简单的JSF2页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <f:facet name="first">
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>Simple OOM Check</title>
        </f:facet>
    </h:head>
    <h:body>
        <h:outputText value="#{oomCheckBean.testString}"/>
    </h:body>
</html>
在此之后,我将JMeter测试用例更改为login,调用这个oomCheck.xhtml页面并注销。过了一会儿,我停止了测试执行,并使用JMX首先手动调用垃圾收集器(java.lang.Memory-->Operations-->gc()。在此之后,我调用方法来创建堆转储(com.sun.management.hospotdiagnostic-->Operations-->dumpHeap())


结果就像我在问题中提到的,内存中有很多OomCheckBean对象。所有者对象是
org/jboss/as/web/deployment/ConcurrentReferenceHashMap$HashEntry
。感谢您对解决此问题的任何帮助。正如我前面提到的,如果JSF版本升级到2.1.16,这些@ViewScope bean将被销毁,留下其他“bug”,比如缺少doctype和AJAX问题。所以,如果有人知道如何在会话无效时销毁@ViewScope bean,我会很高兴。

我不确定是否理解您的问题。您的具体问题是视图作用域bean的
@PreDestroy
在会话过期时从未被调用(这是问题2561已经解决的问题;请注意,问题仅仅是方法调用,而不是实际的销毁!),还是它们即使在会话过期后仍保留在内存中?后者绝对不是这样。它们不应该在任何地方被引用,也不应该迟早被GC'ed引用。您确定自己没有在其他地方引用它们吗?您是否绝对肯定您已经正确地观察到了具体问题?感谢您的快速响应。问题是后者。会话过期后,@viewscope bean将保留在内存中。为了触发OOM错误,我只需编写一个JMeter测试用例,它使用50个线程登录和注销,并在最后使用-XX:+heapdumponAutofmemoryError创建一个堆转储。堆转储中充满了ViewScoped bean,它们还附加了SessionScoped bean。好的,这些session scoped bean是否在别处引用?例如,在应用程序范围的bean中?是的,但正如我在回答中指出的,在没有任何引用的视图范围的bean中也会发生这种情况。您好,您是否碰巧在没有升级到2.1.16的情况下解决了这个问题?感谢您的反馈:)只是一个问题,@ViewScoped仅在您注销或多次访问其他页面后(使用'com.sun.faces.numberOfViewsInSession'和'com.sun.faces.numberOfLogicalViews')才会被销毁?
@ViewScoped
@ManagedBean(name = "oomCheckBean")
public class OomCheckBean implements Serializable {
    private static final long serialVersionUID = 6325712415478215045L;

    private String testString;

    @PostConstruct
    public void init() {
        testString = "Hello World";
        System.out.println("I will survive ....");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("... klaaatsch!");
    }

    /**
     * @return the testString
     */
    public String getTestString() {
        return testString;
    }

    /**
     * @param testString the testString to set
     */
    public void setTestString(String testString) {
        this.testString = testString;
    }
}