python - 在使用 Redis 发布/订阅的 Python 服务中调试内存泄漏

标签 python python-2.7 memory-leaks redis redis-py

我正在尝试使用 Redis 发布/订阅功能构建 Python 2.7 服务。我在 Ubuntu 12.04 上使用 redis 2.8.17 和 redis-py 2.10.3 作为客户端。不幸的是,我的服务似乎正在泄漏内存。内存消耗似乎随着服务接收/消耗/处理的消息量线性增加。

我尝试使用工具 memory_profiler 对其进行调试通过装饰我的主订阅循环。为了让它连续打印输出,我将其更改为每收到一百条消息就退出一次。输出如下所示:

Line #    Mem usage    Increment   Line Contents
================================================
    62     39.3 MiB      0.0 MiB       @memory_profiler.profile
    63                                 def _listen(self, callback):
    64     40.1 MiB      0.7 MiB           for _ in self.redis_pubsub.listen():
    65     40.1 MiB      0.0 MiB               self.count += 1
    66     40.1 MiB      0.0 MiB               self._consume(callback)
    67     40.1 MiB      0.0 MiB               if self.count == 100:
    68     40.1 MiB      0.0 MiB                   self.count = 0
    69     40.1 MiB      0.0 MiB                   break
    70     40.1 MiB      0.0 MiB           gc.collect()

它报告说,每向该服务推送一百条消息,就会出现类似的增长。回调是实际执行应用程序操作的函数,所以如果我的应用程序代码出现问题,第 65 行实际上是我期望内存增加的地方..

输出让我怀疑是 redis 客户端,所以我还使用 pympler.asizeof 检查了 self.redis_pubsub 和 redis.StrictRedis 对象的大小。这些对象一开始很小,并且在服务接收消息时根本不会增加。

此外,当尝试使用 pympler.muppy 和 pympler.summarize 寻找泄漏对象时,它不会报告任何增长的对象计数或任何累积的内存。此外,内存消耗和增长的总数与 Linux 中 top 提供的数字不同。

我被卡住了,有没有人知道可能会发生什么或对我如何进一步调试有任何想法?

最佳答案

我花了几个小时在 pub/sub 设置中调试相同的问题。确实存在内存泄漏,我在发布消息时找不到避免它的方法。我的转变是使用 multiprocessing 在单独的进程上运行发布部分。这对我有用,因为我每隔几秒就会发布一次消息,所以这是一个合理的权衡。

一个没有泄漏的替代方案是 tornadis

关于python - 在使用 Redis 发布/订阅的 Python 服务中调试内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27295022/

相关文章:

python - Scipy 频谱图与 Matlab 频谱图

python - 为什么 Python 调用 __str__ 而不是返回 long 值

python - 在 Django Web 应用程序中访问 models.py 中的用户 uri 方案

python - 为指向 ctypes 结构的指针释放内存时出错?

c++ - 使用复制构造函数时,是否在复制构造函数之前初始化了类数据成员?

python - 使用 Python 通过 HTTP 下载压缩内容

Python 子进程 Grep

python - 使用 Twisted 的 twisted.web 类,我如何刷新传出缓冲区?

python - 如何在使用捕获组时修改字母数字字符的正则表达式

Android:图库中的内存不足异常