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

Mac下Python多进程线性搜索出现应用内存不足问题排查

单进程与多进程线性搜索性能测试问题分析

问题描述

我正在编写程序对比单进程与多进程实现线性搜索的性能。在搭载M2芯片、16GB内存、12核的MacBook Pro上运行时,弹出"应用内存不足"错误,进程甚至未启动;使用较小的nums数组时,进程可运行但多进程版本速度反而更慢。我希望测试大规模场景(小规模下进程开销会抵消性能提升),请问我哪里操作有误?

提供的代码

import random
import math
import time
from multiprocessing import Process, Value
import os

def fastLinearSearch(nums, startIndex, randNumToFind, chunkSize, foundNumber, start_time):
    print('start index: ' + str(startIndex))
    print('chunk size: ' + str(chunkSize))
    if foundNumber == randNumToFind:
        print('done with ' + str(os.getpid()))
        return
    for i in range(startIndex, startIndex + chunkSize):
        if foundNumber == randNumToFind:
            print('done with ' + str(os.getpid()))
            return
        if randNumToFind == nums[i]:
            print('Found number ' + str(randNumToFind))
            print("Took " + str(time.time() - start_time) + " seconds")
            foundNumber = randNumToFind
            print('done with ' + str(os.getpid()))
            return
    print("done and didn't find anything with pid: " + str(os.getpid()))

if __name__ == '__main__':

    nums = []

    print('Generating nums array')
    for i in range(1000000000):
        nums.append(i)
    print('Nums array generated')
    # mix up numbers
    # print("Mixing up numbers...")
    # random.shuffle(nums)
    # print('Mixed up numbers')
    randNum = math.floor(random.random() * len(nums))

    # regular linear search
    print("Linear search for number " + str(randNum))
    start_time = time.time()
    for i in range(len(nums)):
        if (nums[i] == randNum):
            print("Found " + str(randNum))
            print("Took " + str(time.time() - start_time) + " seconds")
            break

    # multiprocessing linear search
    print("Fast linear search for number " + str(randNum))
    start_index_1 = 0
    processes_count = 4
    start_index_2 = math.floor(len(nums) / processes_count) * 1
    start_index_3 = math.floor(len(nums) / processes_count) * 2
    start_index_4 = math.floor(len(nums) / processes_count) * 3

    chunkSize = math.floor(len(nums) / processes_count)
    start_time = time.time()
    foundNumber = Value('d', -1)  # start at -1, a change shows it was found
    p1 = Process(target=fastLinearSearch, args=(
        nums, start_index_1, randNum, chunkSize, foundNumber, start_time))
    p2 = Process(target=fastLinearSearch, args=(
        nums, start_index_2, randNum, chunkSize, foundNumber, start_time))
    p3 = Process(target=fastLinearSearch, args=(
        nums, start_index_3, randNum, chunkSize, foundNumber, start_time))
    p4 = Process(target=fastLinearSearch, args=(
        nums, start_index_4, randNum, chunkSize, foundNumber, start_time))
    p1.start()
    p2.start()
    p3.start()
    p4.start()

    p1.join()
    p2.join()
    p3.join()
    p4.join()

错误点分析

1. 内存占用超限

  • 生成10亿元素的列表nums,每个Python int对象(小整数)约占28字节,10亿个元素总内存约28GB,远超你的16GB内存,直接触发"内存不足"错误。
  • 多进程模式下,Unix系统默认用fork创建子进程,虽然是写时复制,但父进程在创建子进程前已完全生成并修改了nums列表,会导致每个子进程复制整个列表,内存占用直接翻4倍,进一步加剧内存耗尽问题。

2. 共享变量使用错误

  • 代码中直接用foundNumber == randNumToFind比较,foundNumber是Value对象,不是数值,应该访问其.value属性(即foundNumber.value == randNumToFind)。
  • 修改共享变量时,foundNumber = randNumToFind只是给局部变量赋值,并未修改共享内存中的值,其他进程无法感知目标已找到,会继续无效遍历。

3. 进程逻辑冗余与开销问题

  • 即使某个进程找到目标,其他进程无法及时终止,因为共享变量未正确更新,导致不必要的计算浪费。
  • 小规模数组场景下,进程创建、内存复制的开销远大于线性搜索本身的耗时,直接导致多进程版本更慢。

4. 测试场景不真实

  • 代码中nums是有序的(未执行shuffle),单进程搜索完全不需要遍历,直接通过randNum即可定位,这会让单进程测试结果失真,无法真实对比性能。

优化建议

1. 内存优化

  • 避免生成超大列表:如果是模拟无序场景,可以用生成器或直接通过逻辑判断元素值,不需要存储全部元素;如果必须用数组,使用multiprocessing.Array或shared_memory实现内存共享,避免每个进程复制数据。
  • 缩小测试规模先验证逻辑:比如先测试1000万元素的数组,确认多进程逻辑正确后再逐步放大。

2. 修复多进程逻辑

  • 正确使用共享变量:所有对foundNumber的访问和修改都要操作.value属性。
  • 增加进程退出判断:在遍历循环中定期检查foundNumber.value,一旦发现目标已找到就立即退出。
  • 使用Pool管理进程:替代手动创建多个Process,代码更简洁,且能自动处理进程调度。

3. 测试场景修正

  • 确保数组是无序的:取消shuffle的注释,让线性搜索的场景更真实,否则有序数组应该用二分搜索,线性搜索没有对比意义。
  • 多进程测试前先释放单进程的内存:单进程测试完成后,手动删除nums并调用gc.collect()回收内存,再启动多进程测试,避免内存叠加。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:20:56