【发布时间】:2012-08-24 08:28:32
【问题描述】:
在 JBoss 7.1.1 上的 JavaEE6 项目(EJB3、JSF2)中,我们似乎有SeamFaces @ViewScoped 的内存泄漏。
我们制作了一个小原型来验证事实:
- 我们使用 JMeter 调用一个页面 200 次;
- 该页面包含并调用一个视图范围的 bean,该 bean 注入一个有状态的 EJB;
- 我们将会话超时时间固定为 1 分钟。
在测试结束时,我们用 VisualVM 检查内存的内容,我们得到了什么:
- 使用
@ViewScopedbean,我们仍然获得 200 个有状态的MyController实例 - 并且永远不会调用@PreDestroy方法; - 使用
@ConversationScopedbean,@preDestroy方法被称为会话结束,然后我们得到一个干净的内存。
我们是否错误地使用了视图范围,或者它真的是一个错误?
这是 XHTML 页面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:s="http://jboss.org/seam/faces">
<f:metadata>
<f:viewParam name="u" value="#{myBean.uselessParam}" />
<s:viewAction action="#{myBean.callService}" />
</f:metadata>
<h:body >
<f:view>
</f:view>
</h:body>
</html>
现在包含 bean myBean。对于@ConversationScoped 变体,所有已注释的部分均未注释。
@ViewScoped
// @ConversationScoped
@Named
public class MyBean implements Serializable
{
@Inject
MyController myController;
//@Inject
//Conversation conversation;
private String uselessParam;
public void callService()
{
//if(conversation.isTransient())
//{
// conversation.begin();
//}
myController.call();
}
public String getUselessParam()
{
return uselessParam;
}
public void setUselessParam(String uselessParam)
{
this.uselessParam = uselessParam;
}
}
然后是注入的有状态beanMyController:
@Stateful
@LocalBean
public class MyController
{
public void call()
{
System.out.println("call ");
}
@PreDestroy
public void destroy()
{
System.out.println("Destroy");
}
}
【问题讨论】:
标签: jsf-2 memory-leaks cdi seam3 view-scope