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

使用memory_profiler分析Python内存管理时遇到的疑问

关于Python内存分析(memory_profiler)的疑问解答

嘿,我来帮你拆解这个内存分析的问题~先把你的代码、执行命令和结果整理清楚,再针对这类场景的常见疑问做解答:

你的代码与分析信息

代码示例

import copy
import memory_profiler

@profile
def function():
    x = list(range(1000000)) # allocate a big list
    y = copy.deepcopy(x)
    del x
    return y

if __name__ == "__main__":
    function()

执行命令

$ python -m memory_profiler memory_profiler_demo.py

部分分析结果

Filename: memory_profiler_demo.py
Line #    Mem usage    Increment  Line Contents
===============================================
     4     30.074 MiB   30.074 MiB  @profile
     5                             def function():
     6     61.441 Mi...

核心疑问解答(结合这类场景的常见困惑)

我猜你大概率是疑惑:明明执行了del x删除了大列表,为什么内存占用没有明显下降?或者深拷贝后的内存变化不符合预期?下面逐个解释:

1. del x到底做了什么?

del x不是直接释放内存,它只是移除了变量名x对那个大列表对象的引用。Python的垃圾回收(GC)基于引用计数机制:当一个对象的引用计数降到0时,GC才会回收这个对象并释放其占用的内存。

但这里有个细节:如果此时还有其他隐藏引用(比如内存分析工具本身持有临时引用,或者函数栈里的残留引用),那这个列表对象的引用计数不会立刻降到0,自然不会被回收。

2. 深拷贝的内存增长逻辑

从你的结果看,第6行创建x后,内存从30.074MiB涨到61.441MiB,这完全合理:一个包含1000000个元素的列表,在64位系统下大概占用30MB左右(列表存储的是元素指针,每个指针8字节,加上列表本身的结构开销)。执行copy.deepcopy(x)时,内存会再涨差不多30MB——因为深拷贝会创建一个完全独立的新列表,所有元素都是原列表元素的拷贝(这里是int,虽然小整数是共享的,但列表本身是新的)。

3. 为什么del x后内存没下降?

即使del x让列表的引用计数降到了0,CPython也可能不会立刻把内存还给操作系统——它会把释放的内存保留在自己的内存池中,供后续新对象分配使用。另外,memory_profiler是按行采样内存的,可能在del x那一行的采样时刻,GC还没来得及触发回收。

如果你想看到内存立刻下降,可以手动触发GC试试:

import copy
import memory_profiler
import gc

@profile
def function():
    x = list(range(1000000)) # allocate a big list
    y = copy.deepcopy(x)
    del x
    gc.collect()  # 手动触发垃圾回收
    return y

if __name__ == "__main__":
    function()

这时候再看del x之后的内存变化,应该会明显下降。

4. 函数返回后的内存变化

当函数执行完毕返回y,如果调用者没有把y赋值给任何变量(就像你的代码里那样),那么y的引用计数也会降到0,GC会回收y对应的列表。但memory_profiler默认只跟踪函数内部的内存变化,所以函数返回后的内存释放不会显示在报告里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:12:35