Dav*_*vid 15 java testing junit unit-testing memory-leaks
我正在考虑Java程序的自动内存泄漏检测.基本算法是创建包含以下逻辑的JUnit:
Call System.gc() several times
Determine initial heap memory consumption using either Runtime class or JMX
Loop
Do something that exercises program under test
End loop
Call System.gc() several times
Determine final heap memory consumption
Compare initial and final memory numbers
Run Code Online (Sandbox Code Playgroud)
该循环用于查看内存是否以小增量爬升.
有必要区分内存使用的预期和意外增加.
这不是一个单元测试.但是JUnit框架使用起来很方便.
你认为这种方法有效吗?您是否认为这种方法可以成功识别内存泄漏?你做过这样的事吗?
And*_*ong 18
我为内存泄漏开发了一个简单的单元测试框架,这对我来说是可靠的.基本思想是创建一个对象的弱引用,该对象应该被垃圾收集,执行测试,执行完整的GC,然后验证弱引用是否已被清除.
这是一个使用我的框架的相当典型的回归测试:
public void testDS00032554() throws Exception {
Project testProject = getTestProject();
MemoryLeakVerifier verifier = new MemoryLeakVerifier(new RuntimeTestAction(getTestClassMap()));
testProject.close();
verifier.assertGarbageCollected("RuntimeTestAction should be garbage collected when project closed");
}
Run Code Online (Sandbox Code Playgroud)
这里有一些注意事项:
这是完整的帮助程序类,以防您想要尝试它:
/**
* A simple utility class that can verify that an object has been successfully garbage collected.
*/
public class MemoryLeakVerifier {
private static final int MAX_GC_ITERATIONS = 50;
private static final int GC_SLEEP_TIME = 100;
private final WeakReference reference;
public MemoryLeakVerifier(Object object) {
this.reference = new WeakReference(object);
}
public Object getObject() {
return reference.get();
}
/**
* Attempts to perform a full garbage collection so that all weak references will be removed. Usually only
* a single GC is required, but there have been situations where some unused memory is not cleared up on the
* first pass. This method performs a full garbage collection and then validates that the weak reference
* now has been cleared. If it hasn't then the thread will sleep for 50 milliseconds and then retry up to
* 10 more times. If after this the object still has not been collected then the assertion will fail.
*
* Based upon the method described in: http://www.javaworld.com/javaworld/javatips/jw-javatip130.html
*/
public void assertGarbageCollected(String name) {
Runtime runtime = Runtime.getRuntime();
for (int i = 0; i < MAX_GC_ITERATIONS; i++) {
runtime.runFinalization();
runtime.gc();
if (getObject() == null)
break;
// Pause for a while and then go back around the loop to try again...
try {
EventQueue.invokeAndWait(Procedure.NoOp); // Wait for the AWT event queue to have completed processing
Thread.sleep(GC_SLEEP_TIME);
} catch (InterruptedException e) {
// Ignore any interrupts and just try again...
} catch (InvocationTargetException e) {
// Ignore any interrupts and just try again...
}
}
PanteroTestCase.assertNull(name + ": object should not exist after " + MAX_GC_ITERATIONS + " collections", getObject());
}
Run Code Online (Sandbox Code Playgroud)
}
归档时间: |
|
查看次数: |
5023 次 |
最近记录: |