PyTorch张量不大且无需梯度却占大量内存的原因及解决办法
问题原因及解决办法
为什么sys.getsizeof(t)显示72字节却占用10GB内存?
sys.getsizeof(t)只能获取Python层面Tensor对象本身的内存大小(仅包含形状、步幅等元数据),完全不包含张量存储的实际数据。实际数据的内存占用要这么计算:
print(f"实际数据内存: {t.numel() * t.element_size()} Bytes")
按你的张量尺寸[3,429,1080,1920]、float32(每个元素4字节)计算:
3×429×1080×1920×4 = 2668723200 Bytes ≈ 2.5GB
那为什么memory_profiler显示占用10GB?核心原因是PyTorch的CPU内存分配器默认使用内存池机制:
- 它会预先分配大块内存,或者保留已释放的内存供后续复用,不会立即将空闲内存还给操作系统
- memory_profiler统计的是进程的驻留内存(RSS),包含了内存池里的空闲内存、内存碎片等,并非全是被张量占用的活跃内存
另外,torch.permute本身是返回张量视图(仅改变数据访问的步幅,不复制数据),你看到的0.8MB增量只是视图对象的微小开销,不是数据复制导致的。
如何释放内存?
1. 显式清理张量引用+触发垃圾回收
在不需要张量时,手动删除引用并触发Python垃圾回收,让PyTorch有机会回收内存:
del my_tensor import gc gc.collect() # 清理PyTorch CPU内存缓存 torch._C._emptyCPUCache()
2. 调整PyTorch内存分配器行为
通过环境变量让内存分配器更积极地释放内存给操作系统:
- 启动脚本前设置:
该配置会让内存分配器在内存空闲时主动释放给系统export PYTORCH_MALLOC_CONF=expandable_segments:True - 或者强制使用系统默认分配器(关闭PyTorch内存池):
但这种方式可能降低内存分配效率,适合内存紧张的场景export PYTORCH_USE_MALLOC=system
3. 避免不必要的张量持有
确保代码中没有意外保留张量的引用(比如全局变量、未关闭的上下文),让垃圾回收能及时清理无用的张量。
内容的提问来源于stack exchange,提问作者RR_28023
相关产品推荐
相关产品推荐

