【发布时间】:2013-10-09 19:23:35
【问题描述】:
所以我有一个问题,我需要任何关于如何解决这个问题的信息。 我们在 JBoss 7.1 上使用 JSF 2.1,并且我们使用具有与该视图相关的表的视图范围 bean。该表中表示为一行的对象非常大。
每次刷新这些视图时,都会创建该 bean 的一个新实例。
为了验证这是否发生,我创建了一个演示示例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:outputText value="#{viewScopedBean.i}" />
</h:body>
</html>
这个模板然后链接到一个像这样定义的bean:
@ManagedBean
@ViewScoped
public class ViewScopedBean {
private int i = 0;
@PostConstruct
public void init(){
System.out.println("Init - " + i);
}
@PreDestroy
public void dest(){
System.out.println("Destroy - " + i);
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
每次我使用浏览器刷新按钮或在浏览器地址字段中按 Enter 刷新视图时,我都会清楚地看到 @PostConstruct 方法调用。
如果我让应用程序长时间处于活动状态,我看不到 @PreDestroy 方法被调用,并且进行堆转储显示 ViewScopedBean 具有与我重新加载视图的数量相同的实例数,即使我销毁会话,它似乎仍保留在堆上。
这对我来说是个大问题,因为如果 500 个用户用那个大表重新加载视图,JBoss 就会死掉,因为它的堆空间已满。
这是@ViewScoped beans 的设计行为还是我做错了什么?
【问题讨论】: