2012-10-26 29 views
7

Trong dự án JavaEE6 của chúng tôi (EJB3, JSF2) trên JBoss 7.1.1, có vẻ như chúng tôi có rò rỉ bộ nhớ với hạt @ViewScoped. Những ngày cuối cùng của cây tôi đã dành thời gian cho việc điều tra vấn đề này. Vì vậy, tôi đã tạo dự án đơn giản với hai trang để đảm bảo rằng sau khi trang đầu tiên rời khỏi @ViewScoped bean sẽ được phát hành.View ViewScoped beans dẫn đến rò rỉ bộ nhớ

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

và tất cả nghĩ đến cũng đến khi tôi đã thêm phụ thuộc vào @ViewScoped khác đậu

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

} 

Và sau đó không ai đậu đã được phát hành. Có ai biết cách đối phó với nó không? Đây có phải là một lỗi hoặc nó có thể được cấu hình ở đâu đó?

+0

Tham khảo liên kết này. Làm việc xung quanh được thực hiện cho JSf 2.1 & 2.2 http://stackoverflow.com/questions/12182844/memory-leak-with-viewscoped-bean –

Trả lời

5

Thật không may, bạn đã đúng, Đã xảy ra sự cố với việc quản lý bộ nhớ @ViewScoped (và không quan tâm đến việc chuỗi các lượt xem) như bạn sẽ thấy herehere. Ngoài ra, hãy xem this question Những gì bạn có thể thử nghiệm là sử dụng đối tượng UIViewRoot cho mỗi phiên hiện tại và gọi getViewMap().remove("myView") dựa trên một số sự kiện. Bạn cũng có thể thử this

Không liên quan đến điều này, tại sao bạn lại chọn các hạt có phạm vi xem? Chúng được dự định sẽ được sử dụng như tên, cho các khung nhìn. Bạn có bị hạn chế sử dụng SessionScoped không?

+0

Tôi mặc dù được thiết kế cho các khoảng thời gian ngắn hơn của hoạt động của người dùng. Vì vậy, đậu là sống cho đến khi bạn rời khỏi trang hiện tại. Sessionscoped sống lâu hơn, cho đến khi phiên web giảm. Vì vậy, sự lựa chọn của tôi là để tiết kiệm bộ nhớ. – bohdanius

+1

@bohdanius, tôi cho rằng bạn đã có sẵn một phiên phạm vi trong ứng dụng web của mình và nếu bạn làm, bất kỳ thứ gì bạn lưu trữ trong phạm vi xem mà bạn cần tham chiếu qua 3 chế độ xem riêng biệt sẽ được giữ ở đó. Sau đó bạn có thể chịu trách nhiệm làm sạch nó lên (bằng cách thiết lập các vars để null hoặc bất cứ điều gì) hoặc có nó bị phá hủy cùng với phiên. Nếu bạn không thiết lập bean phiên, đây là trường hợp mạnh mẽ cho một bean. Một lựa chọn khác là phạm vi flash, được áp dụng chủ yếu nếu ba lượt xem là tuần tự – kolossus