链接的ViewScoped bean导致内存泄漏

boh*_*ius 9 out-of-memory jsf-2 view-scope

在JBoss 7.1.1上的JavaEE6项目(EJB3,JSF2)中,似乎我们有@ViewScoped bean的内存泄漏.最后一天,我花时间在这个问题调查上.所以我创建了两个页面的简单项目,以保证在第一页离开@ViewScoped bean之后将被释放.

<context-param>  //web.xml
   <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
   <param-value>server</param-value>
</context-param>
<context-param>
   <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name>
   <param-value>false</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)

TreeBean.java

@ManagedBean
@ViewScoped
public class TreeBean implements Serializable {
 private TreeNode root;  
 public static AtomicInteger count = new AtomicInteger(0);

@Override
protected void finalize() throws Throwable {
    System.out.println("TreeBean beans count: " + count.decrementAndGet() + " (FINALISATION)");
}


public TreeBean() {  
    super();
    System.out.println("TreeBean beans count: " + count.incrementAndGet() + " (INITIALISATION)");
}  
Run Code Online (Sandbox Code Playgroud)

first.xhtml

  ....
  <h:form id="frm">
        <p:tree
            value="#{treeBean.root}"
            var="node"
            id="tree">
    ....
   <p:commandLink
            action="second.xhtml?faces-redirect=true"
            value="toSecond" />
    ....            
Run Code Online (Sandbox Code Playgroud)

second.xhtml

  ....
  <h:form id="frm">
    ....
   <p:commandLink
            action="first.xhtml?faces-redirect=true"
            value="toFirst" />
    ....
Run Code Online (Sandbox Code Playgroud)

系统输出:

  INFO  [stdout] (http--0.0.0.0-8080-4) TreeBean beans count: 1 (INITIALISATION)
  INFO  [stdout] (http--0.0.0.0-8080-4) TreeBean beans count: 2 (INITIALISATION)
  INFO  [stdout] (http--0.0.0.0-8080-4) TreeBean beans count: 3 (INITIALISATION)
  ......
  INFO  [stdout] (Finalizer) TreeBean beans count: 2 (FINALISATION)
  INFO  [stdout] (Finalizer) TreeBean beans count: 1 (FINALISATION)
  INFO  [stdout] (Finalizer) TreeBean beans count: 0 (FINALISATION)
Run Code Online (Sandbox Code Playgroud)

所有的想法一直很好,直到我将依赖添加到其他@ViewScoped bean

TreeBean.java

@ManagedBean
@ViewScoped
public class TreeBean implements Serializable {
 private TreeNode root;  

@ManagedProperty(value = "#{treeNodeBean}")
private TreeNodeBean treeNodeBean;


 public static AtomicInteger count = new AtomicInteger(0);

@Override
protected void finalize() throws Throwable {
    System.out.println("TreeBean beans count: " + count.decrementAndGet() + " (FINALISATION)");
}


public TreeBean() {  
    super();
    System.out.println("TreeBean beans count: " + count.incrementAndGet() + " (INITIALISATION)");
}  
Run Code Online (Sandbox Code Playgroud)

TreeNodeBean.java

@ManagedBean
@ViewScoped
public class TreeNodeBean implements Serializable {

     private String treeNodeItem="TreeNodeItem";

}
Run Code Online (Sandbox Code Playgroud)

之后没有一个豆子被释放.有人知道如何处理它吗?这是一个错误还是可能在某处配置?

kol*_*sus 6

不幸的是,你是对的,@ViewScoped内存管理存在已知的问题(并不关心只是链接视图),你会在这里这里看到.另外看看这个问题您可以尝试的是UIViewRoot按照当前会话获取对象并getViewMap().remove("myView")根据某些事件进行调用.你也可以试试这个

与此无关,为什么你链接视图范围豆?它们旨在用于视图的命名.你是否受限于使用SessionScoped