You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多进程中使用只读共享内存(NumPy数组)的内存增长问题排查

共享内存NumPy数组在进程池中的内存增长问题

我基于Python共享内存文档实现了一个最小示例,在进程池的工作进程调用的函数中访问基于共享内存的NumPy数组。按预期,代码的额外内存开销应该极小——只有解释器和非共享变量会产生少量开销,16GB的数组内存不会被复制。

示例代码如下:

import numpy as np
from multiprocessing import Pool, shared_memory
from itertools import product
from tqdm import tqdm

if __name__ == "__main__":
    a_shared_memory = shared_memory.SharedMemory(create=True, size=8_000_000_000)
    a = np.ndarray((20, 100, 100, 100, 100), np.float32, buffer=a_shared_memory.buf)
    b_shared_memory = shared_memory.SharedMemory(create=True, size=8_000_000_000)
    b = np.ndarray((20, 100, 100, 100, 100), np.float32, buffer=b_shared_memory.buf)
            
    def test_func(args):
        a[args] + b[args[:-1]]
        
    with tqdm(total=20 * 100 * 100 * 100) as pbar:  
        with Pool(16) as pool:
            for _ in pool.imap_unordered(test_func,
                                         product(range(20), range(100), range(100), range(100)),
                                         chunksize=16):
                pass

但实际运行时,每个进程的内存占用(top命令显示的RES和SHR指标)随时间持续增长,增长速率可以通过test_func中选取的数组大小调整。

这让我很困惑:这些数组存储在共享内存中,我认为对它们的视图操作不会产生内存分配(我在Linux环境测试,仅读取操作不应触发复制)。而且我甚至没有存储计算结果,完全不清楚为什么会有内存分配。

补充两个观察:

  • 有说法提到,即使读取/访问共享内存中的数组也会触发复制+写入,因为需要更新引用计数。但这应该仅影响约4KB的头内存页,为什么内存会持续增长?
  • 若把代码修改为如下形式,问题就会解决——内存正常共享,没有额外开销,也不会出现持续增长的情况:
def test_func(args):
    a[args], b[args[:-1]]

更新:当我把test_func改为a[0, 0, 0, 0] + b[0, 0, 0]时,问题也会消失。这是不是意味着NumPy数组内部存在某种引用计数器,当访问的索引变化时会导致内存增长,而索引固定时则不会?

我希望能在test_func中执行简单计算(比如访问共享内存、加法、矩阵-向量乘法等),恳请帮助我掌握共享内存的正确使用方法。

内容的提问来源于stack exchange,提问作者Acoop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:40:25