如何编写单元测试来确定对象是否可以被垃圾回收? [英] How can I write a unit test to determine whether an object can be garbage collected?
问题描述
关于我之前的问题,我需要检查将由 Castle Windsor 实例化的组件在我的代码使用完后是否可以被垃圾收集.我已经尝试过上一个问题的答案中的建议,但它似乎没有按预期工作,至少对于我的代码而言.所以我想写一个单元测试来测试在我的一些代码运行后是否可以垃圾收集特定的对象实例.
In relation to my previous question, I need to check whether a component that will be instantiated by Castle Windsor, can be garbage collected after my code has finished using it. I have tried the suggestion in the answers from the previous question, but it does not seem to work as expected, at least for my code. So I would like to write a unit test that tests whether a specific object instance can be garbage collected after some of my code has run.
这有可能以可靠的方式进行吗?
Is that possible to do in a reliable way ?
编辑
我目前根据 Paul Stovell 的回答进行了以下测试,结果成功:
I currently have the following test based on Paul Stovell's answer, which succeeds:
[TestMethod]
public void ReleaseTest()
{
WindsorContainer container = new WindsorContainer();
container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();
container.AddComponentWithLifestyle<ReleaseTester>(LifestyleType.Transient);
Assert.AreEqual(0, ReleaseTester.refCount);
var weakRef = new WeakReference(container.Resolve<ReleaseTester>());
Assert.AreEqual(1, ReleaseTester.refCount);
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.AreEqual(0, ReleaseTester.refCount, "Component not released");
}
private class ReleaseTester
{
public static int refCount = 0;
public ReleaseTester()
{
refCount++;
}
~ReleaseTester()
{
refCount--;
}
}
我是否正确假设,基于上述测试,我可以得出结论,在使用 NoTrackingReleasePolicy 时,Windsor 不会泄漏内存?
Am I right assuming that, based on the test above, I can conclude that Windsor will not leak memory when using the NoTrackingReleasePolicy ?
推荐答案
我通常这样做:
[Test]
public void MyTest()
{
WeakReference reference;
new Action(() =>
{
var service = new Service();
// Do things with service that might cause a memory leak...
reference = new WeakReference(service, true);
})();
// Service should have gone out of scope about now,
// so the garbage collector can clean it up
GC.Collect();
GC.WaitForPendingFinalizers();
Assert.IsNull(reference.Target);
}
注意:您应该在生产应用程序中调用 GC.Collect() 的次数非常非常少.但泄漏测试是合适的例子之一.
NB: There are very, very few times where you should call GC.Collect() in a production application. But testing for leaks is one example of where it's appropriate.
这篇关于如何编写单元测试来确定对象是否可以被垃圾回收?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!