使用dotMemory Unit发现并修复内存问题

目录

编辑说明

何时使用dotMemory Unit?

dotMemory Unit如何工作

如何使用dotMemory Unit的示例

检查对象

检查内存流量

比较快照

检查内存流量的复杂方案

使用Stand-Alone Launcher

dotMemory单元分析工作区

简讯


dotMemory Unit非常灵活,允许您检查应用程序内存使用的几乎任何方面。

编辑说明

我们都知道单元测试是开发和验证我们在.NET IDE中编写的代码的一个重要方面。我们希望我们的测试覆盖.NET解决方案中最小的隔离代码段,并覆盖尽可能多的代码路径,以确保我们的代码按预期运行。

有时测试代码的逻辑是不够的。虽然内存分析器不是我们大多数人每天都使用的工具,但我们应该更频繁地使用它们。通常,只有在出现问题或修复错误时才会在开发过程中使用它们。如果我们可以在单元测试中使用内存分析器怎么办?然后我们可以安心地知道我们的代码不仅在逻辑上很好地编写,而且还有效地使用内存。

何时使用dotMemory Unit

大多数开发人员会在出现问题时启动内存分析器。我们应该在整个开发过程中制定一个使用内存分析器的计划,而不仅仅是当我们认为我们在代码中发现了一个涉及内存泄漏的错误时。这是一个非常正当的理由,但就像病人病了后才用药物治疗一样。为什么不像我们在自己的生活中那样订阅预防保健呢?我们应该计划,锻炼并遵守测试代码的规范,以确保我们的应用程序使用和使用预期的内存。

我们应该用dotMemory Unit测试什么?首先,我们应该确定我们知道消耗最大内存量的应用程序区域。我们还应测试那些需要处理大量对象的区域,例如涉及来自数据源的数据查询的循环。最后,我们应该检查应用程序如何使用大量内存进行数据通信。我们所有的测试最终都可以在单元测试结束时保存其内存快照,以便我们检查使用模式和行为。

我们还可以使用dotMemory Unit来测试是否正在实例化某些类型的对象并在我们的单元测试所覆盖的代码中使用它们。此外,我们可以使用dotMemory Unit来测试保存的快照和当前内存使用情况之间的差异。

正如我们所看到的,在整个开发过程中有很多方面可以从使用dotMemory Unit增强单元测试中受益。除了使用dotMemory Unit进行单元测试外,该工具还可以支持在开发过程中进行功能和集成测试的需求。现在让我们看看我们如何创建和使用这些特殊的单元测试。

dotMemory Unit如何工作

接下来我们将介绍如何在.NET Framework.NET Core解决方案和项目中使用dotMemory Unit。在我们的.NET解决方案中有两种方法可以包含dotMemory Unit。第一种是将dotMemory Unit NuGet包安装到我们的项目中。在Visual Studio中,我们可以使用以下命令通过Package Manager控制台添加包:

Install-Package JetBrains.DotMemoryUnit

Rider IDE中,我们可以使用NuGet窗口添加JetBrains.DotMemoryUnit包,如下所示。

https://i-blog.csdnimg.cn/blog_migrate/03073f59596c84e25fc1f299159e6fbb.png

我们还可以下载必要的文件(包括独立的dotMemory启动器),并包含和引用.NET解决方案中的库。您可以在dotMemory Unit主页https://www.jetbrains.com/dotmemory/unit/找到下载。

我们可以使用大多数的单元测试框架从ReSharperReSharper’s Test Runner和带有dotMemory单元的Rider中的大多数单元测试框架,包括xUnitNUnitMSTTest。我们还可以从JetBrainsdotCover产品中运行我们的单元测试。只需了解dotMemory Unit本身不是测试运行器,我们将与支持的单元测试框架配合使用。

dotMemory Unit的功能不仅仅是在单元测试中添加新功能。运行单元测试后,我们可以保存可用于与未来单元测试进行比较的内存配置文件快照,也可以在JetBrains dotMemory工具中打开和分析。我们还可以运行从独立的dotMemory Unit可执行文件中使用dotMemory Unit测试创建的单元测试。这将允许我们将我们的测试包含在我们的DevOps工作流程中,例如持续集成(CI)和交付(CD)。

在运行我们的单元测试时,我们将提供额外的菜单选项来在dotMemory Unit下运行我们的测试。

https://i-blog.csdnimg.cn/blog_migrate/8d56c1c75b223a49ff253db74377d922.png

如何使用dotMemory Unit的示例

让我们看看我们在.NET.NET Core解决方案中执行的单元测试中使用dotMemory Unit的几种不同方法。我们将从简单的事情开始,并变得更高级。作为说明,我将使用xUnit框架作为我的单元测试示例。

注意:使用xUnit时,默认情况下不会显示dotMemory Unit的输出。为了使它可见,我们必须指示它在单元测试类的构造函数中使用xUnit的输出助手

https://i-blog.csdnimg.cn/blog_migrate/4ae6987d4c52e7b6efabdc7e1dd13041.png

检查对象

我们可以测试的最有用的案例之一是通过检查内存以查找特定类型的对象来查找泄漏。我们使用此类测试来识别由应用程序中的内存流量引起的性能问题。

https://i-blog.csdnimg.cn/blog_migrate/c8b63018987cfc0dd48997e392c87e02.png

在上面的示例中,我们将lambda表达式传递给Check()方法。只有dotMemory Test使用Run Unit Tests运行测试时才会这样做。传递给lambda表达式的内存对象包含当前执行点的所有内存数据。该GetObjects()方法将返回在第二个lambda表达式中传递的一组Album对象。最后,Assert()将检查以验证在内存对象中只传递了一个Album对象。

检查内存流量

检查内存流量的测试甚至更简单。我们需要做的就是用<span lang="IT">AssertTraffic</span> 属性标记测试。在下面的示例中,我们声明DotMemoryTrafficUnitTest()方法中所有代码分配的内存量不超过1,000个字节。

https://i-blog.csdnimg.cn/blog_migrate/38416312fe063ded24d6919edd56381c.png

比较快照

我们不仅可以使用检查点来比较流量,还可以使用其他类型的快照比较。在下面的示例中,我们断言<span lang="NL">Chinook</span>命名空间中的对象在memoryCheckPoint1与第二个dotMemory.Check()调用之间的间隔内没有垃圾收集幸存。

https://www.codeproject.com/KB/showcase/1270862/image006.png

检查内存流量的复杂方案

如果我们需要获得有关内存流量的更复杂信息,我们可以使用与第一个示例相似的方法。传递给dotMemory.Check()方法的lambda表达式验证实现在memoryCheckPoint1memoryCheckPoint2之间的间隔中创建的<span lang="PT">Album</span>类的对象的总大小小于1000字节。

https://i-blog.csdnimg.cn/blog_migrate/2d74a17aae672c0052f8907387665a43.png

使用Stand-Alone Launcher

如果由于我们的工作地点或我们团队选择的开发工具而无法使用ReSharperRider,该怎么办?如果我们确实希望使用独立的单元测试运行器(而不是Visual StudioRider)运行测试,或者希望将内存测试作为我们持续集成构建的一部分,该怎么办?JetBrains让这些场景变得容易处理!我们可以使用独立的dotMemory Unit可执行文件dotMemoryUnit.exe命令行工具。

dotMemoryUnit.exe用作中介器——它运行独立的单元测试运行器,并在运行的测试中为dotMemory单元调用提供支持。

在最简单的情况下,我们所要做的就是指定单元测试运行器及其参数的路径。例如,在以下示例中,我们要从MainTests.dll运行NUnit测试:

dotMemoryUnit.exe "C:\NUnit 3.11.0\bin\nunit-console.exe" -- "E:\MyProject\bin\Release\MainTests.dll"

默认情况下,如果工具成功完成其工作,则其退出代码为0。当我们在CI服务器上运行该工具时,这不是很方便,因为我们需要知道构建中是否有任何失败的测试。在这种情况下,最好的选择是让dotMemoryUnit.exe返回单元测试运行器的退出代码。为此,我们应该使用--propagate-exit-code参数。例如:

dotMemoryUnit.exe "C:\NUnit 3.11.0\bin\nunit-console.exe" --propagate-exit-code 
                        -- "E:\MyProject\bin\Release\MainTests.dll"

dotMemory单元分析工作区

可以使用独立的JetBrains应用程序dotMemory打开由dotMemory Unit生成和保存的工作区。dotMemory Unit 默认保存* .dmw文件的位置是我们计算机的临时位置(temp)。在某些情况下,我们可能希望重新定义工作区文件的位置。这是在放置在程序集、测试类或测试方法之前的DotMemoryUnitAttribute的帮助下完成的。

https://i-blog.csdnimg.cn/blog_migrate/2492e83704c2b67a5a3080ca20ce87ed.png

在此示例中打开dotMemory将显示两个存储快照的详细信息,并允许我们查看比较和差异。

https://i-blog.csdnimg.cn/blog_migrate/e44147cd6f76e58bc4fe6d9d52bd542a.png

简讯

dotMemory Unit非常灵活,允许您检查应用程序内存使用的几乎任何方面。使用内存测试的方式与应用程序逻辑上的单元测试相同:

  • 在我们手动找到问题(例如泄漏)之后,编写一个覆盖它的内存测试。
  • 编写主动测试测试——确保新产品功能不会产生任何内存问题,例如内存中剩余的对象或大流量。

感谢阅读,请不要犹豫,自己尝试dotMemory Unit!它完全免费,唯一的要求是在您的机器上安装RiderReSharperdotCover

 

原文地址:https://www.codeproject.com/Articles/1270862/Discovering-and-Fixing-Memory-Issues-with-dotMemor

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值