繁体   English   中英

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

[英]Writing a test that checks for memory leaks. What is a feasible approach?

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

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

我想不可能写一些像这样的代码:

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 )。 在创建和销毁对象之后,我需要销毁一些持有引用的其他对象。
如果对其他对象进行了更改,则可能会对我的测试产生一些不良影响。 不想在这里详细介绍细节,但我的测试最终可能因为随机原因而失败。

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

没有为此公开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));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM