单元测试内存泄漏我有一个应用程序,其中存在大量内存泄漏。例如,如果我打开一个视图并关闭它10次,我的内存消耗就会增加,因为视图没有完全清理干净。这些是我的内存泄漏。从测试驱动的角度来看,我想编写一个测试来证明我的泄漏并且(在我修复泄漏之后)断言我修复了它。这样我的代码以后就不会被破解了。简而言之:有没有办法断言我的代码没有从单元测试中泄漏内存?我可以这样做:objectsThatShouldNotBeThereCount=MemAssertion.GetObjects().Count;Assert.AreEqual(0,objectsThatShouldNotBeThereCount);我对分析不感兴趣。我使用Ants探查器(我非常喜欢),但也想编写测试以确保“泄漏”不会回来我正在使用C#/Nunit,但我对有这种哲学的人很感兴趣。.内存消耗增加并不一定表示资源泄漏,因为垃圾收集是不确定的,可能还没有开始。即使您“放手”了对象,只要CLR认为系统上有足够的资源,它就可以自由保留它们。如果你确实知道你确实有资源泄漏,那么你可以使用一个具有显式关闭/处置的对象作为其合同的一部分(对于“使用...”构造)。在这种情况下,如果您可以控制类型,则可以在Dispose实现中标记对象的处置以验证它们是否实际处置,以及是否可以将生命周期管理泄漏到类型的接口中。如果你做后者,你可以对合同处置进行单元测试。在某些情况下,我使用了特定于IDisposable的应用程序(扩展了该接口),添加了用于查询对象是否已被释放的选项。如果接口是在类型上显式实现的,就不会对其接口造成太大的污染。如果您无法控制所讨论的类型,则可以按照其他地方的建议使用内存分析器。(例如Jetbrains的dotTrace。)您不需要需要内存分析器的单元测试。您可以从CLRProfiler开始。当托管类型不小心使用非托管资源时,通常会引入内存泄漏。一个典型的例子是System.Threading.Timer,它将回调方法作为参数。因为定时器最终使用非托管资源,引入了新的GC根,只能通过调用定时器的Dispose方法来释放。在这种情况下,你的类型也应该实现IDisposable否则这个对象将永远不会被垃圾收集(泄漏)。您可以通过执行与此类似的操作来为此场景编写单元测试:varinstance=newMyType();//...//以可能触发创建新GC根的所有方式使用您的实例//...varweakRef=newWeakReference(instance);instance.Dispose();实例=空;GC.收集();GC.WaitForPendingFinalizers();GC.收集();Assert.IsFalse(weakRef.IsAlive);具有以编程方式检查分配的某些对象的数量、内存流量、制作和比较内存快照的功能。您可能能够连接到性能分析API,但看起来您必须在启用性能分析器的情况下开始单元测试。如何创建对象?直接或以某种受控方式。如果控件返回一个扩展版本,其中包含注册它们已被丢弃的终结器。然后GC.Collect();GC.WaitForPendingFinalizers();Assert.IsTrue(HasAllOfTypeXBeenFinalized());更多C#学习教程,希望大家多多关注——longoriginalByteCount=GC.GetTotalMemory(true);SomeOperationThatMayLeakMemory();longfinalByteCount=GC.GetTotalMemory(true);Assert.AreEqual(originalByteCount,finalByteCount);不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
