9

In our JavaEE6 project (EJB3, JSF2) on JBoss 7.1.1, it seems we have a memory leak with @ViewScoped beans. Last tree days I've spent time on this issue investigation. So i've created simple project with two pages to guarantee that after first page leaving @ViewScoped bean will be released.

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

sysout:

  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)

and all thinks came well till I've added dependency to other @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";

}

And after that no one bean has been released. Does somebody know how to deal with it? Does this a bug or it may be configured somewhere?

kolossus
  • 19,953
  • 3
  • 45
  • 94
bohdanius
  • 93
  • 1
  • 4
  • Refer to this link. Work around done for JSf 2.1 & 2.2 http://stackoverflow.com/questions/12182844/memory-leak-with-viewscoped-bean – Sathish Kumar Feb 03 '14 at 18:40

1 Answers1

6

Unfortunately, you're correct, There are known issues with @ViewScoped memory management(and isn't concerned with just chaining the views) as you'll see here and here. Also look at this question What you could experiment with is to get your hands on the UIViewRoot object per the current session and call getViewMap().remove("myView") based on some event. You could also try this

Unrelated to this, why're you chaining view scoped beans? They're intended to be used as named, for views. Are you constrained from using the SessionScoped?

Community
  • 1
  • 1
kolossus
  • 19,953
  • 3
  • 45
  • 94
  • I though vievscoped is designed for shorter periods of user activity. So bean is live till you leave current page. Sessionscoped live longer, till web session drop. So my choice was to save memory. – bohdanius Oct 27 '12 at 06:42
  • 1
    @bohdanius, I presumed you already had a session scoped bean in your web app anyway and if you do, whatever you're storing in the view scope that you need to reference across 3 separate views should be kept there. You can then take charge of cleaning it up(by setting the vars to null or whatever) or having it destroyed along with the session. If you don't have a session bean established, this is a strong case for one. Another alternative is the flash scope, which is applicable mainly if the three views are sequential – kolossus Oct 27 '12 at 07:13