python是否在循环的迭代结束时进行垃圾回收? [英] Does python garbage-collect at the end of an iteration in a loop?

查看:307
本文介绍了python是否在循环的迭代结束时进行垃圾回收?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请遵守以下简单代码:

    import random
    while True:
        L = list( str(random.random()))

问题:如果我让它运行,python会不会耗尽内存?
我问的原因:
此循环的第一次迭代,将创建一个列表,并分配"L"来表示该列表.此循环的下一个迭代将创建另一个列表,将"L"从上一个列表中抽出并分配给新列表.先前的列表已失去参考.之前的列表会被垃圾回收吗?如果不是在每次迭代结束时,但最终我希望如此吗?

Question: if I let this run, will python run out of memory?
reason I am asking:
First iteration of this loop, a list is created, and 'L' is assigned to represent that list. The next iteration of this loop, another list is created, 'L' is yanked from the previous list and and assigned to the new list. The previous list has lost it reference. Is the previous list going to be garbage collected? if not at the end of each iteration, but eventually I hope?

话虽如此,只是将场景进一步扩展到多处理:

Having said that, just expand the scenario a bit further into multiprocessing:

    import random
    while True:
        l1 = list( str(random.random()))            
        pseudo: multiprocessing.Queue.put(l1)
        # how is l1 handled here?
        # is l1 .copy()-ed to the queue or referenced by the queue?
        # is l1 destoryed in this process (this while loop) at the end of iteration?

推荐答案

垃圾收集的主要方法是CPython(该语言的参考实现)中的引用计数.当不再有任何对对象的引用时,它所占用的内存将立即释放,并可以由其他Python对象重用. (它可能会也可能不会释放回操作系统.)有一些永不释放的对象例外:较小的整数,内部字符串(包括文字),空元组None.

The primary means of garbage collection is reference counting in CPython (the reference implementation of the language). When there are no longer any references to an object, the memory it occupies is freed immediately and can be reused by other Python objects. (It may or may not ever be released back to the operating system.) There are a few exceptions of objects that are never freed: smallish integers, interned strings (including literals), the empty tuple, None.

因此,为回答您的第一个问题,L将在每次迭代时重新分配给新列表.届时,先前的列表将没有引用,并且其内存将立即释放.

So to answer your initial question, L is going to be reassigned to a new list on each iteration. At that point, the previous list has no references and its memory will be released immediately.

关于第二个示例,将某些内容放入multiprocessing队列中必然是复制操作.必须将该对象序列化(用Python措辞是"picked")才能发送到新进程,该进程具有自己的内存空间,看不到原始进程的内存.在循环中将li重新分配给下一个列表时,上一个列表没有引用,并且将再次释放.

With regard to your second example, putting something into a multiprocessing queue is, of necessity, a copy operation. The object must be serialized ("pickled" in Python parlance) to be sent to the new process, which has its own memory space and can't see anything from the original process's memory. When, in your loop, you reassign li to the next list, the previous list has no references and, again, will be released.

在循环结束时,Ll1变量仍引用一个列表:您在循环的最后一次迭代中创建的列表.如果要释放该对象,则分别为del Ldel l1.

At the end of your loop, the L or l1 variable still refers to a list: the one you created in the last iteration of the loop. If you want to release this object, just del L or del l1 respectively.

PS-当对象包含对自身的引用(直接或通过其他对象链间接)时,则称为循环引用.这些不是通过引用计数自动收集的,Python有一个单独的垃圾收集器,该垃圾收集器会定期运行以清理它们.

PS -- When objects contain references to themselves (either directly, or indirectly through a chain of other objects), this is referred to a cyclic reference. These aren't collected automatically by reference counting and Python has a separate garbage collector which runs periodically to clean them up.

这篇关于python是否在循环的迭代结束时进行垃圾回收?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆