蟒内存泄漏[关闭](Python memory leaks [closed])

2019-07-18 07:06发布

我有一个长期运行的脚本,如果我们足够长的时间运行,将消耗所有我的系统上的内存。

不深入有关脚本的详细信息,我有两个问题:

  1. 是否有任何“最佳实践”跟随,这将有助于防止泄漏的发生?
  2. 是什么技术有在Python调试内存泄漏?

Answer 1:

看看这篇文章: 跟踪蟒蛇内存泄漏

另外,还要注意的是, 垃圾收集模块实际上可以有调试标志设置。 看看set_debug功能。 另外,看看这段代码通过Gnibbler确定类型已在通话后创建的对象。



Answer 2:

我尝试了前面提到的大多数选项,但发现这个小而直观的包装是最好的: pympler

这是相当直截了当地跟踪那些不垃圾收集的对象,看看这个小例子:

经由安装包pip install pympler

from pympler.tracker import SummaryTracker
tracker = SummaryTracker()

# ... some code you want to investigate ...

tracker.print_diff()

输出显示你已经添加的所有对象,再加上他们所消耗的内存。

输出示例:

                                 types |   # objects |   total size
====================================== | =========== | ============
                                  list |        1095 |    160.78 KB
                                   str |        1093 |     66.33 KB
                                   int |         120 |      2.81 KB
                                  dict |           3 |       840 B
      frame (codename: create_summary) |           1 |       560 B
          frame (codename: print_diff) |           1 |       480 B

这个软件包提供了一些更多的功能。 检查pympler的文档 ,尤其是部分识别内存泄漏 。



Answer 3:

让我推荐mem_top工具,
,帮助我解决了类似的问题。

它只是即时显示在一个Python程序内存泄漏顶部的嫌疑人。



Answer 4:

你应该专门对你的全局或静态数据看(长期居住数据)。

当这个数据的增长没有限制,你还可以得到麻烦在Python。

垃圾收集器只能收集数据,未提及任何更多。 但你的静态数据可以联播应该释放的数据元素。

另一个问题是存储周期,但至少在理论上,垃圾收集器应该找到并消除周期 - 至少只要他们不沉迷于一些长期居住数据。

什么样的生活长的数据是特别麻烦? 对任何列表和字典很好看 - 他们可以没有任何限制地扩大。 在词典中,你甚至可以不看,因为当您访问类型的字典的麻烦来了,钥匙在字典的数量可能不是很大的知名度,你的...



Answer 5:

Tracemalloc模块被集成为在Python 3.4开始内置模块,并appearently,它也可用于Python的以前版本的第三方库 (没有测试过,虽然)。

该模块能够输出精确的文件和分配的大多数内存线。 恕我直言,这种信息infinitly比分配情况的每种类型的数量更有价值(这最终被大量的元组的时间,这是一个线索99%,但在大多数情况下,几乎没有帮助)。

我建议你结合使用tracemalloc与pyrasite 。 9次了10年,运行的前10段在pyrasite壳会给你足够的信息和提示,以在10分钟内修复泄漏。 然而,如果你仍然无法找到泄漏的原因,pyrasite壳与本主题中提到的其他工具的组合将可能给你一些更多的提示了。 你也应该采取由pyrasite提供的所有额外的帮助(比如内存查看器)看看。



Answer 6:

为了检测和定位为长时间运行的进程的内存泄漏,例如在生产环境中,您现在可以使用stackimpact 。 它采用tracemalloc下方。 在更多信息这篇文章 。



Answer 7:

不知道“最佳实践”为蟒蛇内存泄漏,但蟒蛇被它的垃圾收集器应该清除它自己的内存。 所以主要是我想通过检查一些短期的循环列表,因为它们不会被垃圾收集器被拾起启动。



Answer 8:

这绝不是详尽的建议。 但一两件事以避免未来的内存泄漏(循环)的思想写作时要记住的是确保任何它接受一个回调的参考,应存储的回调视为弱引用。



Answer 9:

至于最佳实践,保持眼睛的递归函数。 在我来说,我遇到了递归问题(这里有没有必要来定)。 我在做什么,一个简单的例子:

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    if my_flag:  # restart the function if a certain flag is true
        my_function()

def main():
    my_function()

在这种循环方式运行将不会触发垃圾收集和清除功能的遗体,所以通过内存使用量每次都是在不断扩张。

我的解决办法是拉递归调用了创建my_function()和主要有()处理时再调用它。 这样的功能自然结束后自己清理。

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    .....
    return my_flag

def main():
    result = my_function()
    if result:
        my_function()


文章来源: Python memory leaks [closed]