2012-10-26 2 views
7

JBoss 7.1.1의 JavaEE6 프로젝트 (EJB3, JSF2)에서 @ViewScoped 빈을 사용한 메모리 누수가있는 것 같습니다. 지난 수일 동안이 문제 조사에 시간을 보냈습니다. 그래서 첫 페이지가 @ViewScoped 빈을 떠난 후에 릴리스 될 것이라는 것을 보장하기 위해 두 페이지로 된 간단한 프로젝트를 만들었습니다.연결된 ViewScoped 빈이 메모리 누수로 이어짐

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

,369 나는 다른 @ViewScoped 콩

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

} 

에 그리고 아무도 후에 의존성을 추가 한까지 1,363,210

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) 

모든 생각 잘했다 콩이 풀렸다. 누군가 그것을 다루는 방법을 알고 있습니까? 이 버그가 있거나 어딘가에 구성 될 수 있습니까?

+0

이 링크를 참조하십시오. vievscoped는 짧은 기간의 사용자 작업을 위해 설계되었지만, JSF 2.1 및 2.2에 대한 작업은 완료되었습니다. http://stackoverflow.com/questions/12182844/memory-leak-with-viewscoped-bean –

답변

5

불행하게도, 당신이 @ViewScoped 메모리 관리에 문제가 알려져있다 (그냥보기 체인과 관련되지 않은) 당신이 herehere를 볼 수 있습니다로, 맞아요. 또한 this question에서 실험하십시오. 현재 세션 당 UIViewRoot 개체를 사용하고 어떤 이벤트에 따라 getViewMap().remove("myView")으로 전화를 걸어 보는 것이 좋습니다. 시도해 볼 수도 있습니다 this

왜 이와 관련이 없습니까? 뷰 범위가 지정된 bean을 체인화하는 이유는 무엇입니까? 조회 용으로 명명 된 것으로 사용하기위한 것입니다. SessionScoped을 사용하도록 제한 되었습니까?

+0

콩은 현재 페이지를 나갈 때까지 생방송입니다. 웹 세션이 종료 될 때까지 Sessionscoped가 더 오래 삽니다. 그래서 나의 선택은 기억을 저장하는 것이 었습니다. – bohdanius

+1

@ bohdanius, 나는 당신이 이미 웹 애플리케이션에서 세션 스코프 된 bean을 가지고 있다고 가정하고 만약 그렇다면, 뷰 범위에 저장하고있는 것은 무엇이든간에 3 개의 분리 된 뷰를 통해 참조 할 필요가있다. 그런 다음 vars를 null로 설정하거나 세션과 함께 삭제하도록하여 해당 작업을 정리할 수 있습니다. 세션 Bean을 설정하지 않은 경우, 이는 매우 중요합니다. 또 다른 대안은 플래시 범위입니다. 주로 세 가지보기가 순차적 인 경우 적용 할 수 있습니다 – kolossus