2012-10-26 12 views
7

Nel nostro progetto JavaEE6 (EJB3, JSF2) su JBoss 7.1.1, sembra che ci sia una perdita di memoria con i bean @ViewScoped. Ultimi giorni dell'albero ho passato del tempo in questa inchiesta sul problema. Quindi ho creato un progetto semplice con due pagine per garantire che dopo la prima pagina che lascia il bean @ViewScoped verrà rilasciato.Linked ViewI fagioli raccolti portano a perdite di memoria

<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) 

e tutto è venuto pensa bene fino Ho aggiunto la dipendenza da altri @ViewScoped fagioli

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

} 

E dopo che nessuno bean è stato rilasciato. Qualcuno sa come affrontarlo? Questo è un bug o può essere configurato da qualche parte?

+0

Fare riferimento a questo link. Work around done for JSf 2.1 & 2.2 http://stackoverflow.com/questions/12182844/memory-leak-with-viewscoped-bean –

risposta

5

Purtroppo, siete sulla strada giusta, ci sono problemi noti con @ViewScoped gestione della memoria (e non riguarda solo il concatenamento i punti di vista), come vedrete here e here. Guarda anche this question Ciò che potresti sperimentare è mettere le mani sull'oggetto UIViewRoot per la sessione corrente e chiamare lo getViewMap().remove("myView") in base ad alcuni eventi. Potresti provare anche this

Non correlato a questo, perché stai concatenando i fagioli con scope vista? Sono destinati ad essere usati come denominati, per le visualizzazioni. Sei vincolato dall'uso di SessionScoped?

+0

I though vievscoped è progettato per periodi più brevi di attività dell'utente. Quindi il bean è attivo finché non lasci la pagina corrente. Le sessioni memorizzate durano più a lungo, fino alla fine della sessione web. Quindi la mia scelta era di salvare la memoria. – bohdanius

+1

@bohdanius, presumevo che avessi già un bean con scope di sessione nella tua app web e, se lo fai, qualunque cosa tu stia memorizzando nell'ottica della vista che hai bisogno di referenziare attraverso 3 viste separate dovrebbe essere tenuto lì. È quindi possibile prendere in carico di pulirlo (impostando i vars a null o qualsiasi altra cosa) o averlo distrutto insieme alla sessione. Se non si dispone di un bean di sessione stabilito, questo è un caso forte per uno. Un'altra alternativa è l'ambito del flash, che è applicabile principalmente se le tre viste sono sequenziali – kolossus