【问题标题】:Is it possible to monitor copy on write for forked linux processes? (specifically python)是否可以监视 fork linux 进程的写入时复制? (特别是蟒蛇)
【发布时间】:2018-12-04 19:46:57
【问题描述】:

我有一组共享一个大对象的python进程(共享是通过在初始化对象后分叉进程来完成的)

我注意到一个奇怪的内存泄漏:

  • 进程内存(VSZ 和 RSS)几乎没有变化
  • 系统总内存稳步增加

我的猜测是共享对象确实发生了变化(它在“逻辑上”是只读的,但即使只是从中读取,一些内部私有变量也可能发生变化)——这会导致内存页面被复制

有没有办法验证这一点?

【问题讨论】:

  • 什么样的对象?一个列表?字典?熊猫数据框?您有权访问源代码吗? (对象的)
  • 熊猫数据框
  • stackoverflow.com/questions/14224068/… 这有关系吗?如果是这样,那可能是特定于操作系统的,您可能会在完成大量工作后尝试通过执行gc.collect() 手动触发垃圾收集。

标签: python linux memory-leaks fork


【解决方案1】:

要回答您的具体问题“有没有办法验证这一点?”,如果我理解正确,如果您想查看是否有与包含大对象的页面相关的任何更改,您可以执行以下操作。

1) 确定“大型共享对象”的地址以及该对象的结束地址。

2) 如果起始地址不在 4K 页面边界上,则将起始地址向下舍入到对象开始之前的页面边界。

3) 如果结束地址不在 4K 边界上,则将结束地址向上舍入到对象结束处之后的页面边界。

4) 将进程及其所有子进程的内存范围转储到单独的文件并进行比较。

但是,我认为Will os.fork() use copy on write or do a full copy of the parent-process in Python? 可能已经为至少一些需要复制的写作提供了解释。具体来说,python 对象是引用计数的,您的子进程将改变引用计数。

您是否考虑过使用 python 的线程而不是创建子进程?

【讨论】:

  • 关于引用计数的参考很可能是最好的解释
【解决方案2】:

您可以尝试以下方法:

dtrace -n wp_page_copy:entry'/pid == 11111/ { @counts[ustack()] = count(); }'

不确定wp_page_copy 是否仅限于在写时复制期间使用。我似乎记得读过它,但我不会在没有确认的情况下打赌。您需要将 11111 更改为您的 python pid。

【讨论】:

    猜你喜欢
    • 2014-10-24
    • 2013-06-28
    • 2010-09-16
    • 2020-07-27
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2013-07-16
    相关资源
    最近更新 更多