del仅解除变量绑定,gc.collect()才触发实际内存回收;jupyter中需配合使用,否则对象可能因残留引用无法释放。

del 和 gc.collect() 必须配合用,单删变量不等于释放内存
Jupyter Notebook 运行变慢,90% 的情况不是硬件问题,而是内核里堆了太多没清理的对象。Python 的垃圾回收器不会立刻释放内存,尤其在 Jupyter 这种长期运行的内核中——变量删了,内存可能还挂着。
-
del只是解除名字绑定,对象若还有其他引用(比如被plt.show()缓存、被display()持有、或被日志/调试器悄悄引用),就不会被回收 -
gc.collect()才真正触发回收,但默认只回收“可到达性”已断的对象;有些对象(如循环引用的 matplotlib 图形)需要手动干预 - 常见陷阱:只写
del df就以为完事,结果df.head()之前生成的DataFrame预览对象仍驻留内存
建议每次清理大对象后都跟一句:
import gc del large_df gc.collect()
如果仍卡顿,加一行检查:gc.get_count() —— 返回三元组,第三项持续增长说明有未回收对象。
%reset -f 是最狠的清内存方式,但会丢掉所有变量
%reset -f 不是“重启内核”的替代品,它是直接清空当前内核的命名空间,比 del 更彻底,也更危险。
- 它会删除所有变量(包括你忘了名字的临时变量),但不会重置已导入的模块状态(比如
matplotlib的全局配置、logging级别、torch.cuda.memory_allocated()状态) - 如果你依赖某些全局设置(如
pd.options.display.max_rows = 1000),执行后得重设 - 它不释放 GPU 内存(PyTorch/TensorFlow),也不清掉
plt.gcf()持有的 figure 引用
适用场景:
- 单元格反复跑出错,怀疑变量污染(比如同名变量类型突变)
- 想快速验证某段代码是否真能跑通,不依赖历史状态
- 调试时确认某个 bug 是否和旧变量有关
慎用场景:
- 正在迭代模型训练,
model和optimizer都在内存里 - 使用了
%store或%recall跨 notebook 传参
执行后建议补一句:%who 确认变量已清空。
c.MappingKernelManager.cull_idle_timeout 防止后台内核吃光内存
VS Code 或 JupyterLab 启动多个 notebook 时,常出现“明明没运行,内存却越涨越高”的现象。这是因为闲置内核没被自动回收,默认不启用 culling(驱逐)机制。
- 默认值是
0(禁用),意味着内核只要开着就永远不死,哪怕你半小时没点它 - 设置
c.MappingKernelManager.cull_idle_timeout = 600(单位秒),表示空闲超 10 分钟就杀掉 - 必须配合
c.MappingKernelManager.cull_interval = 300(每 5 分钟检查一次),否则不生效
配置位置:
- 全局:修改
~/.jupyter/jupyter_notebook_config.py或~/.jupyter/jupyter_server_config.py - 临时:启动时加参数
jupyter lab --MappingKernelManager.cull_idle_timeout=600
注意:这个设置对当前正在执行的单元格无效,只管“无消息交互”的内核。如果你跑着一个 time.sleep(3600),它不会被误杀。
pd.set_option('display.max_rows', 20) 不只是让表格好看,是防浏览器崩
Jupyter 把 DataFrame 渲染成 HTML 表格时,会把全部数据转成字符串塞进 DOM。10 万行 × 50 列的表,光 HTML 就几十 MB,浏览器直接卡死或崩溃。
-
pd.set_option('display.max_rows', 20)控制行数上限,但列数也要设:pd.set_option('display.max_columns', 10) - 更激进的做法:
pd.set_option('display.large_repr', 'truncate'),强制截断长字符串和数组 - 如果你真需要看全量数据,改用
df.to_csv('debug.csv')导出再查,别硬渲染
副作用:设得太小会影响调试(比如看不出分布异常),建议在探索阶段设宽松值(max_rows=1000),导出前再收紧。
内存占用真正的“大头”往往不是数据本身,而是前端渲染生成的 DOM 节点。这点容易被忽略。











