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

Python Ray远程函数调用时大对象重复拷贝 共享内存未生效问题

核心原因

你的代码写法本身没有问题,出现多进程重复占用内存的核心原因是Ray的共享内存零拷贝机制不支持普通Python嵌套对象:

  • 你存储的是由字典组成的Python列表,属于非连续内存布局的原生Python对象,Ray序列化这类对象时依赖pickle协议,工作进程访问对象时必须在自身的私有Python堆内存中完整反序列化重建整个对象,无法直接映射共享内存段实现零拷贝访问,因此每个进程都会持有一份独立的5GB+副本,这就是你在任务管理器中看到内存暴涨的直接原因。
  • 你替换为全1数值数组后内存占用恢复正常,是因为numpy数组属于连续内存块的数值型对象,Ray的Plasma对象存储支持直接将这类对象所在的共享内存段映射到工作进程地址空间,不需要额外拷贝和重建,自然不会产生多份内存副本。
  • 你当前使用的Windows 11环境会进一步放大这个问题:Ray在Windows平台的共享内存基于内存映射文件模拟,对非数值型Python对象的序列化/反序列化效率、共享支持度都弱于Linux/macOS下的原生POSIX共享内存实现,嵌套Python对象的额外内存开销会更明显。
可行解决方法
  • 优先方案:重构数据集格式:把由字典组成的列表转换为numpy结构化数组、Apache Arrow表、pandas DataFrame这类满足连续内存布局、被Ray零拷贝序列化支持的结构化格式,再通过ray.put()提交到对象存储。如果你的字典字段是固定结构,这个改造成本极低,同时还能获得比原生Python字典列表高得多的访问性能。
  • 次选方案:Worker本地加载+系统缓存共享:如果暂时无法重构数据集格式,不要通过ray.put()传递整个大对象,改为在每个Ray工作进程启动初始化时,从本地磁盘以只读模式加载一次数据集,借助Windows的系统文件缓存实现跨进程的内存页共享。注意这个方案必须严格保证所有工作进程不会修改加载后的数据集,否则会触发写时复制机制产生独立内存副本。
  • 不推荐方案:保留原生Python对象结构换其他共享方案:如果必须保留字典列表的原生结构,只能换用支持Python原生对象跨进程共享的实现,但这类方案普遍存在全局访问锁、GIL限制等问题,5GB级别的数据规模下性能表现会远差于Ray的零拷贝共享机制。
快速验证方法

你可以在提交对象后调用ray.available_resources()配合Windows任务管理器的详细内存页查看:如果Ray对象存储的驻留内存中仅存在一份5GB左右的对象,但每个Ray工作进程的私有内存占用仍然达到5GB级别,即可确认是反序列化产生私有副本的问题,和你的代码调用逻辑无关。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:18:31