我有一个关于内存管理/内存泄漏的问题,我想澄清一下。
设置:
我正在测试一些servlet代码,它接受HttpServletRequest和HttpResponse对象引用HttpServletRequest#getParameter(String),HttpServletRequest#getHeader(String)和HttpServletRequest#getAttribute(String)。
我正在为servlet代码编写单元测试。为了允许测试,我已经为HttpServletRequest和HttpServletResponse创建了允许测试的存根。示例代码如下:
public final class HttpServletRequestStub implements HttpServletRequest {
private Map<String, String> parameterMap = new HashMap<String, String>();
private Map<String, String> headerMap = new HashMap<String, String>();
private Map<String, String> attributeMap = new HashMap<String, String>();
public void setParameter(String param, String value) {
this.parameterMap.put(param, value);
}
public void setHeader(String param, String value) {
this.headerMap.put(param, value);
}
@Override
public void setAttribute(String param, String value) {
this.attributeMap.put(param, value);
}
public void flush() {
this.parameterMap.clear();
this.headerMap.clear();
this.attributeMap.clear();
}
@Override
public String getParameter (String parameter) {
return this.parameterMap.get(parameter);
}
@Override
public String getHeader(String parameter) {
return this.headerMap.get(parameter);
}
@Override
public String getAttribute(String attribute) {
return this.attributeMap.get(attribute);
}
.... Other stubbed methods
}
在我的单元测试中:
public class MyTest {
private MyServlet servlet;
private HttpServletRequest request;
private HttpServletResponse response;
@Before
public void setUp() throws Exception {
request = new HttpServletRequestStub();
response = new HttpServletResponseStub(); // Not in the sample code but implemented.
servlet = new MyServlet();
}
@After
public void tearDown() throws Exception {
request = null;
response = null;
servlet = null;
}
@Test
public void testFoo() throws Exception {
request.setParameter("foo", "bar");
request.setAttribute("attrib", "attrib");
request.setHeader("header", "header");
servlet.service(request, response);
}
}
我的问题是关于内存管理。我是否有必要在测试执行后刷新假标题,请求和属性映射内容,或者一旦请求,响应对象在我的拆卸方法中解除引用(用@After注释),它是否会自动发生?我是否必须在我的拆卸方法中明确调用flush方法来清除内存引用?我想我可能需要使用Weak HashMap而不是HashMap为存根映射设置弱的引用,但我不知道这是否是正确的选择。我仔细阅读了article,现在还不清楚。任何帮助都会有用。
谢谢,
卡尔蒂克
答案 0 :(得分:1)
取消引用对象应该足够了。 Java垃圾收集器删除所有无法访问的对象,即没有可帮助访问它们的引用。如果您怀疑对象真的消失了,可以使用任何可用的java分析器。
顺便说一下,我可以建议你使用一个可用的Mock对象实现,而不是自己实现像SerbletRequestStub这样的东西吗?例如,请参阅EasyMock。还有一个建议。有JUnit扩展已经实现了所有与Web相关的存根。请参阅Apache Cactus。答案 1 :(得分:0)
由于单元测试独立性,JUnit为每个测试方法创建了新的MyTest对象。
即,在不同的MyTest实例中调用testFoo()
和testBar()
。您的代码足以解决内存问题,在这种情况下甚至不需要tearDown()
。由于以前的MyTest实例可用于GC,因此如果没有其他任何参考,它的成员也可用于GC。