测试-使用测试套件捕获内存泄漏

目录

使用测试套件捕获内存泄漏

资源泄漏是一种令人不快的错误类型。你的程序逐渐使用更多的内存、文件描述符或其他有限的资源。一切似乎都正常——直到你运行程序,结果程序崩溃了。

在许多情况下,你可以通过调整测试套件提前捕获这类错误。或者,在你发现此类错误后,可以使用测试套件来识别导致泄漏的原因。本文将介绍:

  • 内存泄漏的示例。
  • 何时使用测试套件可能是识别泄漏原因的好方法。
  • 如何使用 pytest 捕获泄漏。
  • 其他类型的泄漏。

内存泄漏

通常,你的程序会分配一些内存,然后最终释放它。在 Python 中,一旦对象不再有任何引用(或更准确地说,没有来自模块或运行代码的引用),内存会自动释放。在编译语言中,可能需要手动释放内存。

如果你不释放内存会发生什么?随着进程使用越来越多的内存,它最终会变慢、崩溃或被静默杀死。例如,我运行了这个 Python 程序:

$ python -m mypackage

最终它崩溃了;起初我不确定它是否给出了错误消息,因为同时我的终端卡住并不得不被杀死。当我运行 sudo dmesg 时,Linux 内核日志显示了以下内容:

...
[185329.418692] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=user.slice,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/user@1000.service/app.slice/app-gnome-emacs-22313.scope,task=python,pid=729871,uid=1000
[185329.418713] Out of memory: Killed process 729871 (python) total-vm:42680276kB, anon-rss:42213556kB, file-rss:1600kB, shmem-rss:0kB, UID:1000 pgtables:83572kB oom_score_adj:100

程序使用了太多内存,因此操作系统杀死了它。


使用测试套件识别内存泄漏

识别内存泄漏的一种方法是使用内存分析器,如 MemrayFil(更易于使用,但功能较少)或 Sciagraph(专为批处理作业的内存和性能分析设计,适用于开发和生产环境)。但这可能取决于运行时环境和程序类型;例如,Sciagraph 无法帮助你分析生产环境中运行的 Web 服务器,它专为批处理作业设计。

另一种方法是查看是否可以使用测试套件发现内存泄漏。特别是,如果满足以下条件,这种方法可能会奏效:

  1. 你的测试套件有良好的覆盖率。
  2. 内存泄漏易于重现,不会只在罕见的情况下发生。当然,你事先不会知道这一点。
  3. 内存泄漏足够大,可以在运行测试时被注意到。同样,你事先也不会知道这一点。

如果这些条件成立,并且在许多情况下它们确实成立,你可以使用测试套件帮助识别内存(或其他资源泄漏)的来源。特别是对于内存泄漏,对于每个测试:

  1. 在测试运行之前,测量当前使用的内存量。
  2. 测试完成后,再次测量内存使用情况。
  3. 如果第二个数字更高,则表明测试中泄漏了一些内存。

使用 pytest 实现资源泄漏检测

有多种方法可以测量内存使用情况:

  • tracemalloc 是 Python 内置的,测量粒度非常细;缺点是并非所有第三方编译扩展都集成了 tracemalloc,例如 Polars 的内存分配不会显示在那里。
  • 另一个选项是 psutil.Process().memory_full_info().uss,它无法注意到小的分配,但适用于任何库,因为它测量的是进程级别的操作系统信息。

我们将使用 tracemalloc

我们的示例包在 mypackage/tests/ 中有测试,使用流行的 pytest 测试框架运行:

$ pytest
========
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李星星BruceL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值