1

我正在通过 Python 多处理创建几个子进程,但这些子进程即使是空进程也使用大量堆私有内存。在启用了 THP(透明大页面)的 RHEL 上运行时,这种情况会变得更糟。

  • 空子进程的堆私有内存中有什么?
  • 在linux COW(写时复制)下,子进程不应该共享所有内存,因为它不创建/修改任何内存页面?或者子进程正在尝试修改/写入内存页面,那么它正在尝试修改/写入什么样的数据?
  • 还是因为喜欢python对象引用计数或其他原因?

这是一个简单的例子来演示这个:

import os
import multiprocessing

print parent process's heap memory in /proc/<pid>/smaps

def emptyProcess():
    print child process's heap memory in /proc/<pid>/smaps
    return

multiprocessing.Process(name='p1', target=emptyProcess).start()

输出:

parent:  pid: 20920:   rss:8228864, shr:2781184, priv:5447680, swap:0, pss:6154240

child: pid: 20921:   rss:6397952, shr:5472256, priv:925696, swap:0, pss:3381248

子进程的 priv 内存(925696B,或堆中的 664KB)中有什么?

父进程堆内存:

006cc000-00be4000 rw-p 00000000 00:00 0 [堆]

大小:5216 KB

RSS:4120 KB

pss: 4120 KB

Shared_Dirty:0 kB

Private_Dirty:4120 kB

参考:4120 kB

匿名:4120 kB

AnonHugePages:0 kB

内核页面大小:4 kB

子进程堆内存:

006cc000-00be4000 rw-p 00000000 00:00 0 [堆]

大小:5216 KB

RSS:4396 KB

pss: 2530 KB

Shared_Dirty:3732 kB

Private_Dirty:664 kB

参考:676 kB

匿名:4396 kB

AnonHugePages:0 kB

内核页面大小:4 kB

4

1 回答 1

1

每个进程中的主要内容之一是 Python 解释器/VM。如果这是一个 C 程序,您会看到完全不同的画面,但即使使用“空”Python 进程,除非您使用线程,否则您仍然会产生解释器的开销。每个 Python 解释器都有一堆堆、堆栈和代码,Python 的多处理是 Linux 进程的包装器(据我所知);所以基本上你正在处理fork()。分叉一个新进程意味着你得到一个新的 Python 解释器。尽管操作系统在 Copy On Write 方面非常聪明,但 Python 解释器的开销也会增加。

我的建议是尝试 Python 线程,或者将其切换为非解释语言以减少进程开销。

于 2015-08-28T02:50:04.013 回答