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

Python中删除对象后内存无法回收的问题求助

删除numpy数组引用后内存未释放的异常问题

开发过程中,将对象临时存储在列表中,删除对象的所有引用后发现内存仍未释放,导致进程RAM占用过高。复现了一个简单示例,结果不符合预期,代码如下:

import psutil
import os
import gc
import sys
import numpy as np

mod = int(sys.argv[1])
process = psutil.Process(os.getpid())
print(f"Empty memory: {process.memory_info().rss/1e6:.1f}MB")

arrs = list()
for i in range(1000):
    arr = np.arange(50000) * i
    if i % mod == 0:
        arrs.append(arr)
print(f"Memory before cleaning: {process.memory_info().rss/1e6:.1f}MB - {len(arrs)} elements in array")
del arrs
gc.collect()
print(f"Memory after cleaning: {process.memory_info().rss/1e6:.1f}MB")

使用不同参数运行后的结果:

# 1
Empty memory: 33.3MB
Memory before cleaning: 435.4MB - 1000 elements in array
Memory after cleaning: 34.4MB

#2
Empty memory: 33.3MB
Memory before cleaning: 234.2MB - 500 elements in array
Memory after cleaning: 34.5MB

#3 - 为何此场景下内存未被回收?
Empty memory: 33.3MB
Memory before cleaning: 167.8MB - 334 elements in array
Memory after cleaning: 167.8MB

#500
Empty memory: 33.3MB
Memory before cleaning: 35.4MB - 2 elements in array
Memory after cleaning: 34.4MB

疑问

完全不符合预期:为何mod=3时内存未回收?为何数组规模越大内存回收越彻底?


解答

这是numpy底层内存分配器的缓存策略导致的,和Python垃圾回收机制无关:

  • numpy依赖系统级内存分配器(比如Linux下的glibc ptmalloc、Windows下的HeapAlloc)管理内存。释放内存时,分配器不会立刻把所有内存还给操作系统——尤其是小内存块,会被缓存到进程内存池中,供后续内存申请复用,避免频繁向操作系统申请/释放内存的性能开销。
  • 具体到测试用例:
    • mod=1/2时,数组总数量多,每个数组属于较大内存块(单个数组为50000个int64,约390KB)。释放这些大块内存时,分配器判断暂时无复用需求,就会把内存归还给操作系统,因此rss(驻留内存)明显下降。
    • mod=3时,334个数组的总内存约130MB,每个都是400KB级别的小内存块。释放后,分配器将这些内存留在进程缓存池中,不会立刻归还操作系统,所以rss数值看起来无变化。但这些内存可被后续numpy或其他代码复用——你可以尝试在gc.collect()后再创建一批同样大小的数组,会发现内存不再增长,因为复用了缓存的内存。
    • mod=500时仅2个数组,总内存很小,释放后分配器可轻松将小内存块归还给操作系统,因此rss回到初始水平。

另外要注意,rss(Resident Set Size)统计的是进程实际占用的物理内存,包含了分配器缓存的未使用内存。如果想查看程序真正在使用的内存,可以关注numpy内部的内存使用,或者用vms(虚拟内存大小)辅助判断,但vms包含已申请但未使用的虚拟地址空间,参考价值有限。

内存分配器的行为会因操作系统、分配器实现不同而变化,但核心逻辑都是缓存小内存块以提升性能。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 03:07:05