"del" 是什么意思到底是做什么的? [英] What does "del" do exactly?

查看:35
本文介绍了"del" 是什么意思到底是做什么的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

from memory_profiler import profile

@profile
def mess_with_memory():
    huge_list = range(20000000)
    del huge_list
    print "why this kolaveri di?"

这是我从解释器运行时的输出:

This is what the output is, when I ran it from interpreter:

 3      7.0 MiB      0.0 MiB   @profile
 4                             def mess_with_memory():
 5                             
 6    628.5 MiB    621.5 MiB       huge_list = range(20000000)
 7    476.0 MiB   -152.6 MiB       del huge_list
 8    476.0 MiB      0.0 MiB       print "why this kolaveri di"

如果你注意到输出,创建巨大的列表消耗了 621.5 MB,而删除它只释放了 152.6 MB.当我检查 docs 时,我发现了以下声明:

If you notice the output, creating the huge list consumed 621.5 MB while deleting it just freed up 152.6 MB. When i checked the docs, I found the below statement:

the statement del x removes the binding of x from the namespace referenced by the local scope

所以我猜,它并没有删除对象本身,而是解除了它的绑定.但是,它在解除绑定方面做了什么,释放了如此多的空间(152.6 MB).有人可以麻烦解释一下这里发生了什么吗?

So I guess, it didn't delete the object itself, but just unbind it. But, what did it do in unbinding that it freed up so much of space(152.6 MB). Can somebody please take the pain to explain me what is going on here?

推荐答案

Python 是一种垃圾收集语言.如果某个值不再从您的代码可达",它最终会被删除.

Python is a garbage-collected language. If a value isn't "reachable" from your code anymore, it will eventually get deleted.

del 语句,如您所见,删除了变量的绑定.变量不是值,它们只是值的名称.

The del statement, as you saw, removes the binding of your variable. Variables aren't values, they're just names for values.

如果该变量是任何地方对该值的唯一引用,则该值最终将被删除.特别是在 CPython 中,垃圾收集器建立在引用计数之上.因此,最终"的意思是立即".* 在其他实现中,通常是很快".

If that variable was the only reference to the value anywhere, the value will eventually get deleted. In CPython in particular, the garbage collector is built on top of reference counting. So, that "eventually" means "immediately".* In other implementations, it's usually "pretty soon".

如果还有其他对相同值的引用,则只需删除其中一个引用(无论是通过 del xx = None,退出范围 where x 存在,等等)不会清理任何东西.**

If there were other references to the same value, however, just removing one of those references (whether by del x, x = None, exiting the scope where x existed, etc.) doesn't clean anything up.**

这里还有一个问题.我不知道 memory_profiler 模块(大概是这个)实际测量什么,但是描述(谈论 psutil 的使用)听起来像是从外部"测量您的内存使用情况.

There's another issue here. I don't know what the memory_profiler module (presumably this one) actually measures, but the description (talking about use of psutil) sounds like it's measuring your memory usage from "outside".

当 Python 释放存储空间时,它并不总是——甚至通常——将其返回给操作系统.它将空闲列表"保留在多个级别,因此与必须一路返回操作系统请求更多内存相比,它可以更快地重新使用内存.在现代系统上,这几乎不是问题——如果您再次需要存储,那么拥有它就好了;如果您不这样做,它会在其他人需要它时立即被传出并且永远不会被传回,因此没有什么害处.

When Python frees up storage, it doesn't always—or even usually—return it to the operating system. It keeps "free lists" around at multiple levels so it can re-use the memory more quickly than if it had to go all the way back to the OS to ask for more. On modern systems, this is rarely a problem—if you need the storage again, it's good that you had it; if you don't, it'll get paged out as soon as someone else needs it and never get paged back in, so there's little harm.

(最重要的是,我上面所说的操作系统"实际上是一个由多个层次组成的抽象,从 malloc 库到核心 C 库,再到内核/分页器,并且这些级别中至少有一个通常有自己的空闲列表.)

(On top of that, which I referred to as "the OS" above is really an abstraction made up of multiple levels, from the malloc library through the core C library to the kernel/pager, and at least one of those levels usually has its own free lists.)

如果您想从内部的角度跟踪内存使用情况……嗯,这很难.由于新的tracemalloc> 模块.有各种第三方模块(例如,heapy/guppyPymplermeliae) 尝试获取与早期版本相同的信息,但这很困难,因为获取信息在 PEP 445 之前,从各种分配器中获取信息并将该信息绑定到垃圾收集器非常困难.

If you want to trace memory use from the inside perspective… well, that's pretty hard. It gets a lot easier in Python 3.4 thanks to the new tracemalloc module. There are various third-party modules (e.g., heapy/guppy, Pympler, meliae) that try to get the same kind of information with earlier versions, but it's difficult, because getting information from the various allocators, and tying that information to the garbage collector, was very hard before PEP 445.

* 在某些情况下,存在对值的 引用……但仅来自本身无法访问的其他引用,可能在一个循环中.就垃圾收集器而言,这仍然算作无法访问",但就引用计数而言则不然.因此,CPython 也有一个循环检测器",它每隔一段时间运行一次,并找到相互可达但不可达其他任何人的值的循环并清理它们.

* In some cases, there are references to the value… but only from other references that are themselves unreachable, possibly in a cycle. That still counts as "unreachable" as far as the garbage collector is concerned, but not as far as reference counts are concerned. So, CPython also has a "cycle detector" that runs every so often and finds cycles of mutually-reachable but not-reachable-from-anyone-else values and cleans them up.

** 如果您在交互式控制台中进行测试,则可能存在难以跟踪的对您的值的隐藏引用,因此您可能认为当你没有.在脚本中,如果不是容易,也应该总是可能来解决问题.gc 模块可以提供帮助,调试器也可以.但当然,它们为您提供了添加其他隐藏引用的新方法.

** If you're testing in the interactive console, there may be hidden references to your values that are hard to track, so you might think you've gotten rid of the last reference when you haven't. In a script, it should always be possible, if not easy, to figure things out. The gc module can help, as can the debugger. But of course both of them also give you new ways to add additional hidden references.

这篇关于"del" 是什么意思到底是做什么的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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