编写检查内存泄漏的测试。什么是可行的方法?

时间:2014-05-28 09:56:28

标签: c# memory-leaks automated-tests

最近,我修复了一个事件持有实例的泄漏。只用了几个星期,我不得不再次修复同一个物体的泄漏,因为有人添加了另一个导致泄漏的事件。

我现在想添加一些自动测试。此测试应该创建对象,销毁对象并验证对象不再存在于内存中。

我想不可能编写一些代码:

Initialize();
var object = CreateObject();
Type type = object.GetType();
DestroyObject(object);
// There are a few objects that intentionally keep my object still alive
// up to a certain time.
DestroyFurtherObjectsWithReferenceToMyObject();
GC.Collect();
Assert.IsNull(FindInstanceOf(type));

我认为问题是FindInstanceOf方法。 GC类,afaik,没有提供这样的方法。

另一种方法是经常创建对象,每次都会破坏它,然后比较总内存 我觉得这种方法不太可靠。在我的情况下,我必须首先提取应用程序的许多部分(因此Initialize以上)。在创建和销毁对象之后,我需要销毁一些持有引用的其他对象 如果对其他对象进行了更改,则可能会对我的测试产生一些不良影响。不想在这里详细说明,但我的测试最终可能因为随机原因而失败。

那么,找出某个对象是否留在内存中的可能解决方案是什么?

1 个答案:

答案 0 :(得分:2)

没有为此公开API。但是,你可以模仿"一些收藏家所做的工作。在窗帘后面,一些GC类型只是保留一张地图

  

对象引用< =>使用计数器

当某个其他对象指向当前对象时,使用计数器会递增。释放引用时,计数器会递减。您可以做的是为您的对象提供一个使用地图,您可以在测试中查看。示例代码

Initialize();
var object = CreateObject();  // calls ObjectUsageMap.IncrementCountFor(object);
DestroyObject(object);        // calls ObjectUsageMap.DecrementCountFor(object);

// calls ObjectUsageMap.DecrementCountFor(object) inside next line
DestroyFurtherObjectsWithReferenceToMyObject(); 
GC.Collect();
Assert.AreEqual(0, ObjectUsageMap.GetCountFor(object));