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

Python gc.collect()中float自由列表疑问及内存泄漏风险咨询

关于Python中gc.collect()与float对象自由列表的疑问解答

官方文档语句的真实含义

Not all items in some free lists may be freed due to the particular implementation, in particular float.

这句话核心意思是:Python内部的「对象自由列表」机制会缓存一部分已无引用的对象(尤其是float类型),即便调用gc.collect(),这部分缓存对象也不会被彻底释放回操作系统。

这不是说float对象完全无法被垃圾回收,而是Python为了优化性能,会把刚被销毁的float对象暂存在自由列表中,供后续创建新float时直接复用,避免频繁分配/释放内存的开销。

纠正你的误解:float并非完全不回收,int的情况有区别

你提到的[1.0,2.0,3.0]在失去引用后,这些float对象的引用计数会归零,但不会立刻释放给系统,而是被加入float的自由列表缓存;而[1,2,3]里的小整数(-5到256区间)是Python全局缓存的单例对象,不管有没有引用,它们本身就不会被销毁,这和垃圾回收机制无关——如果是超出该范围的大整数,失去引用后会被正常回收,不会进入类似float的自由列表。

直观示例:观测float自由列表的缓存行为

我们可以用tracemalloc观测内存变化,对比float和大整数的回收差异:

import gc
import tracemalloc

# 观测float的内存变化
tracemalloc.start()
l_float = [float(i) for i in range(10000)]
l_float = None
gc.collect()
current, peak = tracemalloc.get_traced_memory()
print(f"float列表回收后,当前内存占用: {current/1024/1024:.2f} MB")
tracemalloc.stop()

# 观测大整数的内存变化
tracemalloc.start()
l_int = [1000000 + i for i in range(10000)]
l_int = None
gc.collect()
current, peak = tracemalloc.get_traced_memory()
print(f"大整数列表回收后,当前内存占用: {current/1024/1024:.2f} MB")
tracemalloc.stop()

运行后会发现,float列表回收后的内存占用略高于大整数情况——这就是部分float对象被保留在自由列表中,未释放给操作系统的证明。后续再创建新float对象时,内存不会明显上涨,因为复用了缓存的对象。

重复调用生成大量float的函数是否会内存泄漏?

不会出现内存泄漏。CPython中float的自由列表有固定大小限制(默认最多缓存100个空闲float对象,不同版本略有调整),当自由列表满了之后,新产生的空闲float对象会被正常释放给操作系统。

用你给出的代码测试(新增内存观测逻辑):

import random
import psutil
import os
import gc

def get_memory_usage():
    process = psutil.Process(os.getpid())
    return process.memory_info().rss / 1024 / 1024  # 单位MB

def f():
    l = [random.uniform(0, 1) for _ in range(100_000_000)]

if __name__ == '__main__':
    count = 1
    while count <= 5:
        print(f"{count=}, 当前内存: {get_memory_usage():.2f} MB")
        f()
        gc.collect()
        print(f"回收后内存: {get_memory_usage():.2f} MB")
        count += 1

运行后可见:第一次调用f()内存大幅上涨,回收后内存下降但不会回到初始值;第二次及之后调用f(),内存不再持续上涨,而是稳定在固定区间——这说明内存占用可控,不存在泄漏问题,只是自由列表缓存了少量float对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:20:36