"del"是什么意思?确切地做? [英] What does "del" do exactly?

查看:183
本文介绍了"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,退出存在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.

(最重要的是,上面我称为"OS"实际上是一个抽象,它由多个层次组成,从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 模块,它在Python 3.4中变得更加容易.有各种第三方模块(例如,heapy/ guppy meliae )试图与早期版本获取相同类型的信息,但是这很困难,因为在 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天全站免登陆