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

Python多进程因内存分配问题停滞的技术咨询

问题分析与解决方案

核心原因

Linux与Windows的内存管理机制差异导致了该现象:

  • 场景1:单进程分配内存接近总内存1/4:四个进程同时申请时,总需求接近系统可用内存上限。Linux内核会优先通过**页交换(Swap)**调度内存,导致进程被内核阻塞(等待内存页从swap加载/写入),无法执行到异常捕获逻辑,因此卡在threading.py的wait方法处。
  • 场景2:单进程分配内存超过总内存:此时内核直接触发OOM Killer终止进程。multiprocessing的Pool会检测到子进程异常退出,进而触发func中的except块,打印"error"并返回None。
  • Windows系统的内存管理不会依赖swap阻塞进程,而是直接拒绝内存分配请求,因此能正常触发异常捕获。

解决方案

1. 禁用Swap(临时生效)

禁用swap后,内核无法通过交换页满足内存需求,会直接拒绝超量的内存分配,触发MemoryError,进程即可进入异常处理流程:

swapoff -a

注意:该操作会影响系统其他进程的内存可用空间,仅适合测试场景。

2. 手动预检查可用内存

使用psutil库提前获取系统可用内存,避免分配接近临界值的内存:

import time
import numpy as np
import psutil

def func(arg):
    try:
        # 获取系统可用内存(字节)
        available_mem = psutil.virtual_memory().available
        # 计算本次分配需要的内存:float64类型,每个元素8字节
        required_mem = 40 * 1024 * 1024 * 128 * 8
        # 预留10%内存,避免触发内核swap调度
        if required_mem > available_mem * 0.9:
            raise MemoryError("Insufficient memory for allocation")
        
        print(f"Start allocating: {arg}")
        a = np.full((40, 1024, 1024, 128), 1.)
        print(f"Done allocating: {arg}")
        time.sleep(1)
        return arg
    except:
        print("error")
        return None
        
if __name__=='__main__':
    import multiprocessing
    with multiprocessing.get_context('spawn').Pool(4) as pool:
        results = pool.map(func, range(4))
    print(results)

3. 调整内存超配参数

修改Linux内核的内存超配策略,让系统直接拒绝超出可用内存的分配请求:

  • 临时生效:
    echo 2 > /proc/sys/vm/overcommit_memory
    
  • 永久生效:编辑/etc/sysctl.conf,添加:
    vm.overcommit_memory=2
    
    然后执行sysctl -p加载配置。

该参数设置为2时,内核会严格检查内存分配请求,仅允许分配不超过可用内存 + 交换分区*swap_ratio的空间,超出时直接返回分配失败,触发MemoryError。


内容的提问来源于stack exchange,提问作者Mads M Pedersen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:35:19