多处理 - 使用 Managers 命名空间来节省内存

Har*_*ton 2 python memory numpy out-of-memory python-multiprocessing

我有几个进程,每个进程都需要一个大的 numpy 数组来完成任务,这只是被读取(线程正在搜索它以寻找适当的值)。

如果每个进程加载数据,我会收到内存错误。

因此,我试图通过使用管理器在进程之间共享相同的数组来最小化内存使用量。

但是我仍然收到内存错误。我可以在主进程中加载一次数组,但是当我尝试将其作为管理器命名空间的属性时,我收到了内存错误。我假设管理器就像指针一样,并允许单独的进程(通常只能访问自己的内存)也可以访问这个共享内存。但是错误提到了酸洗:

Traceback (most recent call last):
  File <PATH>, line 63, in <module>
    ns.pp = something
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\managers.py", line 1021, in __setattr__
    return callmethod('__setattr__', (key, value))
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\managers.py", line 716, in _callmethod
    conn.send((self._id, methodname, args, kwds))
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\connection.py", line 206, in send
    self._send_bytes(ForkingPickler.dumps(obj))
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
MemoryError
Run Code Online (Sandbox Code Playgroud)

我假设 numpy 数组在分配给经理时实际上正在被复制,但我可能错了。

更令人恼火的是,我在一台具有 32GB 内存的机器上,看着内存使用情况,它只会在崩溃前稍微增加一点,最多可能增加 5%-10%。

有人可以解释为什么使数组成为命名空间的属性会占用更多内存吗?为什么我的程序将无法使用一些备用存储avaliable的?(我已经在 SO 上阅读了命名空间管理器文档以及这些管理器命名空间线程。

我正在运行 Windows Server 2012 R2 和 Python 3.5.2 32 位。

这是一些演示我的问题的代码(您需要使用替代文件来代替large.txt,该文件是约 75MB 的制表符分隔字符串):

import multiprocessing
import numpy as np

if __name__ == '__main__':

    # load Price Paid Data and assign to manager
    mgr = multiprocessing.Manager()
    ns = mgr.Namespace()

    ns.data = np.genfromtxt('large.txt')
    # Alternative proving this work for smaller objects
    # ns.data = 'Test PP data'
Run Code Online (Sandbox Code Playgroud)

Aar*_*ron 5

经理类型是为灵活性而不是效率而构建的。他们创建了一个保存值的服务器进程,并且可以将代理对象返回给需要它们的每个进程。服务器和代理通过 tls 通信以允许服务器和代理在不同的机器上,但这必然意味着复制任何对象有问题。我没有一直追踪源,所以额外的副本可能会在使用后被垃圾收集,但至少最初必须有一个副本。

如果你想要共享物理内存,我建议使用Shared ctypes Objects。这些实际上确实指向内存中的一个公共位置,因此速度更快,资源更少。它们不支持全胖 python 对象所做的所有相同的事情,但可以通过创建结构来组织数据来扩展它们。