python - 临时对象的内存消耗和生命周期

标签 python

我有一个 python 代码,其中内存消耗随时间稳定增长。虽然有几个对象可以合法地变得非常大,但我试图了解我观察到的内存占用是由于这些对象造成的,还是只是我在内存中乱扔了没有得到妥善处理的临时对象--- 作为最近从手动内存管理世界转换过来的人,我想我只是不完全理解 python 运行时如何处理临时对象的一些非常基本的方面。

考虑具有大致这种一般结构的代码(省略不相关的细节):

def tweak_list(lst):
    new_lst = copy.deepcopy(lst)
    if numpy.random.rand() > 0.5:
        new_lst[0] += 1  # in real code, the operation is a little more sensible :-)
        return new_lst
    else:
        return lst


lst = [1, 2, 3]
cache = {}

# main loop
for step in xrange(some_large_number):

    lst = tweak_list(lst)    # <<-----(1)

    # do something with lst here, cut out for clarity

    cache[tuple(lst)] = 42   # <<-----(2)

    if step%chunk_size == 0:
        # dump the cache dict to a DB, free the memory (?)
        cache = {}           # <<-----(3)

问题:

  1. tweak_list 中创建的 new_list 的生命周期是多少?它会在退出时被销毁,还是会被垃圾收集(在哪一点?)。重复调用 tweak_list 是否会生成大量长期存在的小列表?
  2. list 转换为 tuple 以用作 dict 键时是否有临时创建?
  3. dict设置为空是否会释放内存?
  4. 或者,我是不是从一个完全错误的角度来处理手头的问题?

最佳答案

  1. new_lst 未返回时函数存在时清理。它的引用计数降为 0,可以进行垃圾回收。在当前的 cpython 实现中立即发生。

    如果返回new_lst 引用的值将替换lstlst 引用的列表看到它的引用计数减少了 1,但是 new_lst 最初引用的值仍然被另一个变量引用。

  2. tuple() 键是存储在 dict 中的值,因此这不是临时值。除了那个元组之外,没有创建额外的对象。

  3. 将旧的 cache dict 替换为新的将减少一个引用计数。如果 cache 是对 dict 的唯一引用,它将被垃圾收集。这会导致所有包含的元组键的引用计数减一。如果没有其他引用,那些将被垃圾收集。

  4. 请注意,当 Python 释放内存时,并不一定意味着操作系统会立即回收它。大多数操作系统只会在其他需要时回收内存,而不是假设程序可能很快再次需要部分或全部内存。

关于python - 临时对象的内存消耗和生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13787549/

相关文章:

python - Django 中的 Zeromq PUSH/PULL

python - 为什么使用 icontains 过滤 django 区分大小写?

python - 随机森林分类器 - 将索引标签标记转换回字符串值

python - Django 实例在 Google App Engine 下启动

python - 绘制 matplotlib 错误栏给出 AssertionError 断言 vertices.ndim == 2

python - 确定从 spacy 中提取的文本是否是一个完整的句子

python - Django : cannot unpack non-iterable int object

python - 如何在不使用 ctrl-c 的情况下关闭 jupyter notebook 应用程序(服务器)?

python - 使用 Requests 包时出现 SSL InsecurePlatform 错误

python - 如何在python中使用mechanize将字符串输入到表单的某个部分?