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

Python多进程写时复制(COW)疑问:4个工作进程仅使内存占用翻倍而非预期的5倍

Python多进程写时复制(COW)疑问:4个工作进程仅使内存占用翻倍而非预期的5倍

这个问题踩中了很多人对COW(写时复制)的误解点,我来帮你拆解清楚~

首先,核心原因是:写时复制的粒度是操作系统的内存页(通常4KB),而不是整个Python对象!你预期的50GB是假设每个子进程会复制整个10GB对象,但实际上只有被修改的那一小块内存对应的页会被复制,这就是内存占用远低于预期的关键。

接下来一步步分析你的场景:

  1. 主进程初始状态:你加载的10GBbytearray(注:bytes是不可变类型,你代码里能做切片赋值说明用的是可变的bytearray)占10GB物理内存,所有内存页在COW机制下处于只读共享状态。
  2. 子进程创建时:操作系统会让子进程和主进程共享所有物理内存页——此时每个子进程的虚拟地址空间里虽然映射了10GB的范围,但物理内存还是只有主进程的10GB,没有任何额外复制。
  3. 子进程修改对象时:你每个子进程只修改了10字节的内容,这10字节只占了1个4KB的内存页(内存页是操作系统的最小分配单位,哪怕改1字节,整个页都会被复制)。所以每个子进程只会新增约4KB的物理内存,4个进程加起来才16KB左右,根本不会让物理内存涨到50GB。

那你看到的20GB是怎么回事?大概率是你混淆了虚拟内存和物理内存:

  • 虚拟内存:每个子进程的虚拟地址空间里会映射10GB的范围(对应主进程的大对象),如果看虚拟内存总和,主进程10GB + 4个子进程各10GB=50GB,但这只是地址空间的映射,不是实际占用的物理内存。
  • 物理内存:实际只有主进程的10GB,加上子进程复制的几个小页,总物理内存应该接近10GB。你看到20GB,可能是内存监控工具的统计方式问题(比如把文件缓存、共享内存也算进去了),或者你的load_large_object用了特殊的加载方式(比如mmap映射文件,修改时触发了文件缓存的写回,额外占用了内存)。

另外还有个小细节:Python的bytearray是可变动态数组,切片修改(比如object[start:start+size] = ...)如果是在已分配的内存范围内,只会直接修改对应内存,不会触发整个对象的重新分配,所以也不会导致整个对象被复制。

最后总结下:
COW是操作系统层面的页级优化机制,和Python对象的大小无关。只有当子进程修改到某个内存页时,该页才会被复制,而不是整个对象。你看到的内存占用远低于预期,正是这个机制在起作用——它避免了不必要的大内存复制,这也是COW的核心优势。

备注:内容来源于stack exchange,提问作者LongTran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:57:59