【问题标题】:Debug CPython memory fragmentation调试 CPython 内存碎片
【发布时间】:2020-08-21 14:47:07
【问题描述】:

我有一个长期运行的 CPython 3.8 进程。一段时间后,它使用了大量的 RAM。 我试过了

  1. 正在运行 gc.collect()
  2. 使用 pymler 发现所有已知的 Python 对象
import gc
import psutil
from pympler import muppy, summarize

gc.collect()
total_ram = psutil.Process().memory_info().rss
all_objects = muppy.get_objects(include_frames=True)
s = summary.summarize(all_objects)
python_objects_size = sum(row[2] for row in s)

输出:102 MiB Python 对象,824 MiB RSS 内存!

[编辑] 3. 使用 tracemalloc;它还返回价值约 100MiB 的 python 对象

[编辑 2]export PYTHONMALLOC=malloc 没有解决问题。

有没有办法查询CPython内存管理器来弄清楚

  • 它拥有多少 RAM,这样我就可以从 RSS 中减去它并确定是否有任何 C 库未使用 PyMem_Malloc 并且正在泄漏
  • 为什么它持有内存(例如,发现它持有一个 64kb 的页面,因为一个 20 字节的 PyObject 仍在被引用)
  • 识别调用 PyMem_Malloc 之后从未释放内存的 C 模块
  • 跟踪操作系统级别的 malloc() 和 free() 并将它们与 pymalloc 执行的进行交叉比较,以确定是否有 C 库分配内存而不是 PyMem_Malloc

相关

【问题讨论】:

  • tracemalloc 发出的信息总计约 100MB - 与 pymler 报告的大致相同。 memory_profiler 给了我被大大低估的结果;例如如果我分配一个包含 100k 随机浮点数的列表,memory_profiles 表示该行消耗了 0.3 MiB,同时它报告 RSS 上升了 3.8 MiB。
  • 不是一个真正的答案......几个月前我们在我的工作中遇到了类似的问题。在花了一些时间使用垃圾收集分析器之后,我们最终使用古老的分而治之的方法解决了这个问题:删除一些代码,看看问题是否仍然存在,而不是删除更多,等等等等(还有一些之后还有更多等等 - 但它让我们最终能够解决问题)。

标签: python garbage-collection


【解决方案1】:

也许尝试不同的内存调试器。可以在 python 中使用valgrind

【讨论】:

    猜你喜欢
    • 2012-12-11
    • 2013-08-14
    • 2010-10-26
    • 2011-08-18
    • 2018-09-25
    • 2011-01-17
    • 2020-02-15
    • 1970-01-01
    相关资源
    最近更新 更多