Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 数组:巨大的临时内存开销_Python_Arrays_Memory_Multiprocessing_Overhead - Fatal编程技术网

Python 数组:巨大的临时内存开销

Python 数组:巨大的临时内存开销,python,arrays,memory,multiprocessing,overhead,Python,Arrays,Memory,Multiprocessing,Overhead,如果我使用python的multiprocessing.Array创建1G共享数组,我发现python进程在调用multiprocessing.Array期间使用了大约30G的内存,然后减少了内存使用。我非常感谢任何能帮助我弄清楚为什么会发生这种情况并解决它的人 下面是在Linux上复制它的代码,内存由smem监控: import multiprocessing import ctypes import numpy import time import subprocess import sys

如果我使用python的multiprocessing.Array创建1G共享数组,我发现python进程在调用multiprocessing.Array期间使用了大约30G的内存,然后减少了内存使用。我非常感谢任何能帮助我弄清楚为什么会发生这种情况并解决它的人

下面是在Linux上复制它的代码,内存由smem监控:

import multiprocessing
import ctypes
import numpy
import time
import subprocess
import sys

def get_smem(secs,by):
    for t in range(secs):
        print subprocess.check_output("smem")
        sys.stdout.flush()
        time.sleep(by)



def allocate_shared_array(n):
    data=multiprocessing.Array(ctypes.c_ubyte,range(n))
    print "finished allocating"
    sys.stdout.flush()


n=10**9
secs=30
by=5
p1=multiprocessing.Process(target=get_smem,args=(secs,by))
p2=multiprocessing.Process(target=allocate_shared_array,args=(n,))
p1.start()
p2.start()
print "pid of allocation process is",p2.pid
p1.join()
p2.join()
p1.terminate()
p2.terminate()
以下是输出:

pid of allocation process is 2285
  PID User     Command                         Swap      USS      PSS      RSS
 2116 ubuntu   top                                0      700      773     1044
 1442 ubuntu   -bash                              0     2020     2020     2024
 1751 ubuntu   -bash                              0     2492     2528     2700
 2284 ubuntu   python test.py                     0     1080     4566    11924
 2286 ubuntu   /usr/bin/python /usr/bin/sm        0     4688     5573     7152
 2276 ubuntu   python test.py                     0     4000     8163    16304
 2285 ubuntu   python test.py                     0   137948   141431   148700

  PID User     Command                         Swap      USS      PSS      RSS
 2116 ubuntu   top                                0      700      773     1044
 1442 ubuntu   -bash                              0     2020     2020     2024
 1751 ubuntu   -bash                              0     2492     2528     2700
 2284 ubuntu   python test.py                     0     1188     4682    12052
 2287 ubuntu   /usr/bin/python /usr/bin/sm        0     4696     5560     7160
 2276 ubuntu   python test.py                     0     4016     8174    16304
 2285 ubuntu   python test.py                     0 13260064 13263536 13270752

  PID User     Command                         Swap      USS      PSS      RSS
 2116 ubuntu   top                                0      700      773     1044
 1442 ubuntu   -bash                              0     2020     2020     2024
 1751 ubuntu   -bash                              0     2492     2528     2700
 2284 ubuntu   python test.py                     0     1188     4682    12052
 2288 ubuntu   /usr/bin/python /usr/bin/sm        0     4692     5556     7156
 2276 ubuntu   python test.py                     0     4016     8174    16304
 2285 ubuntu   python test.py                     0 21692488 21695960 21703176

  PID User     Command                         Swap      USS      PSS      RSS
 2116 ubuntu   top                                0      700      773     1044
 1442 ubuntu   -bash                              0     2020     2020     2024
 1751 ubuntu   -bash                              0     2492     2528     2700
 2284 ubuntu   python test.py                     0     1188     4682    12052
 2289 ubuntu   /usr/bin/python /usr/bin/sm        0     4696     5560     7160
 2276 ubuntu   python test.py                     0     4016     8174    16304
 2285 ubuntu   python test.py                     0 30115144 30118616 30125832

  PID User     Command                         Swap      USS      PSS      RSS
 2116 ubuntu   top                                0      700      771     1044
 1442 ubuntu   -bash                              0     2020     2020     2024
 1751 ubuntu   -bash                              0     2492     2527     2700
 2284 ubuntu   python test.py                     0     1192     4808    12052
 2290 ubuntu   /usr/bin/python /usr/bin/sm        0     4700     5481     7164
 2276 ubuntu   python test.py                     0     4092     8267    16304
 2285 ubuntu   python test.py                     0 31823696 31827043 31834136

  PID User     Command                         Swap      USS      PSS      RSS
 2116 ubuntu   top                                0      700      771     1044
 1442 ubuntu   -bash                              0     2020     2020     2024
 1751 ubuntu   -bash                              0     2492     2527     2700
 2284 ubuntu   python test.py                     0     1192     4808    12052
 2291 ubuntu   /usr/bin/python /usr/bin/sm        0     4700     5481     7164
 2276 ubuntu   python test.py                     0     4092     8267    16304
 2285 ubuntu   python test.py                     0 31823696 31827043 31834136

Process Process-2:
Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "test.py", line 17, in allocate_shared_array
    data=multiprocessing.Array(ctypes.c_ubyte,range(n))
  File "/usr/lib/python2.7/multiprocessing/__init__.py", line 260, in Array
    return Array(typecode_or_type, size_or_initializer, **kwds)
  File "/usr/lib/python2.7/multiprocessing/sharedctypes.py", line 115, in Array
    obj = RawArray(typecode_or_type, size_or_initializer)
  File "/usr/lib/python2.7/multiprocessing/sharedctypes.py", line 88, in RawArray
    result = _new_value(type_)
  File "/usr/lib/python2.7/multiprocessing/sharedctypes.py", line 63, in _new_value
    wrapper = heap.BufferWrapper(size)
  File "/usr/lib/python2.7/multiprocessing/heap.py", line 243, in __init__
    block = BufferWrapper._heap.malloc(size)
  File "/usr/lib/python2.7/multiprocessing/heap.py", line 223, in malloc
    (arena, start, stop) = self._malloc(size)
  File "/usr/lib/python2.7/multiprocessing/heap.py", line 120, in _malloc
    arena = Arena(length)
  File "/usr/lib/python2.7/multiprocessing/heap.py", line 82, in __init__
    self.buffer = mmap.mmap(-1, size)
error: [Errno 12] Cannot allocate memory

从打印语句的格式来看,您使用的是python 2

range(n)
替换为
xrange(n)
,以节省一些内存

data=multiprocessing.Array(ctypes.c_ubyte,xrange(n))
(或使用python 3)

10亿范围大约需要8GB(我刚刚在我的windows PC上试过,但它冻结了:不要这样做!)

尝试使用10**7,以确保:

>>> z=range(int(10**7))
>>> sys.getsizeof(z)
80000064  => 80 Megs! you do the math for 10**9
xrange
这样的生成器函数不需要内存,因为它在迭代时会逐个提供值

在Python3中,他们一定是受够了这些问题,发现大多数人之所以使用
range
,是因为他们想要生成器,于是杀死了
xrange
,并将
range
变成了生成器。现在,如果您真的想将所有号码分配到
列表(范围(n))
。至少你不会错误地分配一个TB

编辑:

OP评论意味着我的解释并不能解决问题。我在我的windows box上做了一些简单的测试:

import multiprocessing,sys,ctypes
n=10**7

a=multiprocessing.RawArray(ctypes.c_ubyte,range(n))  # or xrange
z=input("hello")
在Python2中,上升到500Mb,然后保持在250Mb 升级到500Mb,然后使用python 3保持在7Mb(这很奇怪,因为它至少应该是10Mb…)


结论:好的,它的峰值为500Mb,因此不确定它是否会有帮助,但是您可以在Python 3上尝试您的程序,看看您的总体内存峰值是否较少吗?

不幸的是,问题不在于范围,我只是将其作为一个简单的说明。实际上,这些数据将从磁盘读取。我还可以使用n*[“a”]并在multiprocessing.Array中指定c_char作为另一个示例。当我传递给multiprocessing.Array的列表中只有1G的数据时,它仍然使用大约16G。我想知道是否有一些低效的酸洗正在进行或类似的事情

通过使用tempfile.SpooledTemporaryFile和numpy.memmap,我似乎找到了一个解决方案。我可以打开内存中临时文件的内存映射,必要时将临时文件假脱机到磁盘,并通过将其作为参数传递给multiprocessing.Process,在不同进程之间共享临时文件


我仍然想知道多处理是怎么回事。我不知道为什么它会对1G数据数组使用16G。

如果您使用的是python 2,请将
range(n)
替换为
xrange(n)
不幸的是,问题不在于范围,我只是将其作为一个简单的说明。实际上,这些数据将从磁盘读取。我还可以使用n*[“a”]并在multiprocessing.Array中指定c_char作为另一个示例。当我传递给multiprocessing.Array的列表中只有1G的数据时,它仍然使用大约16G。我想知道是否有一些低效的酸洗正在进行或类似的事情。好的,
range
到此为止。你能发布一个可复制的独立的例子吗?(这里称之为MVCE)