【问题标题】:Linked ViewScoped beans lead to memory leaks链接的 ViewScoped bean 导致内存泄漏
【发布时间】:2012-10-17 00:13:27
【问题描述】:

在我们的 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>

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)");
}  

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" />
    ....            

second.xhtml

  ....
  <h:form id="frm">
    ....
   <p:commandLink
            action="first.xhtml?faces-redirect=true"
            value="toFirst" />
    ....

系统输出:

  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)

在我将依赖项添加到其他 @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)");
}  

TreeNodeBean.java

@ManagedBean
@ViewScoped
public class TreeNodeBean implements Serializable {

     private String treeNodeItem="TreeNodeItem";

}

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

【问题讨论】:

标签: jsf-2 out-of-memory view-scope


【解决方案1】:

不幸的是,您是对的,@ViewScoped 内存管理存在已知问题(并且不关心仅链接视图),您将看到herehere。另请查看this question,您可以尝试在当前会话中获取UIViewRoot 对象并根据某些事件调用getViewMap().remove("myView")。你也可以试试this

与此无关,您为什么要链接视图范围的 bean?它们旨在按名称使用,用于视图。您是否限制使用SessionScoped

【讨论】:

  • 我虽然 vievscoped 是为较短的用户活动而设计的。所以 bean 一直存在,直到您离开当前页面。 Sessionscoped 寿命更长,直到网络会话下降。所以我的选择是节省内存。
  • @bohdanius,我假设你已经在你的网络应用程序中有一个会话范围的 bean,如果你这样做了,无论你在视图范围中存储什么,你需要在 3 个单独的视图中引用应该是留在那里。然后,您可以负责清理它(通过将 vars 设置为 null 或其他)或将其与会话一起销毁。如果您没有建立会话 bean,这是一个强有力的案例。另一种选择是 flash 范围,主要适用于三个视图是顺序的情况
猜你喜欢
  • 2012-08-24
  • 2011-09-16
  • 2015-07-06
  • 2014-06-07
  • 2013-11-20
  • 2011-10-28
  • 2016-01-18
  • 2012-12-13
  • 1970-01-01
相关资源
最近更新 更多