gpt4 book ai didi

python multiprocessing.Array : huge temporary memory overhead

转载 作者:行者123 更新时间:2023-11-28 22:34:38 25 4
gpt4 key购买 nike

如果我使用 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 这样的生成器函数不占用内存,因为它在迭代时一个一个地提供值。

在 Python 3 中,他们一定受够了这些问题,发现大多数人使用 range 是因为他们想要生成器,因此杀死了 xrange 并转为 range 生成器。现在,如果您真的想分配所有必须分配给 list(range(n)) 的数字。至少您不会错误地分配 1 TB!

编辑:

OP的评论说明我的解释没有解决问题。我在我的 windows box 上做了一些简单的测试:

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

a=multiprocessing.RawArray(ctypes.c_ubyte,range(n)) # or xrange
z=input("hello")

上升到 500Mb,然后使用 python 2 保持在 250Mb上升到 500Mb,然后使用 python 3 保持在 7Mb(这很奇怪,因为它至少应该是 10Mb...)

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

关于python multiprocessing.Array : huge temporary memory overhead,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38798330/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com