当前位置: 首页 > 面试题库 >

“ del”到底是做什么的?

柳鸿博
2023-03-14
问题内容

这是我的代码:

from memory_profiler import profile

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

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

 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。当我检查文档时,我发现以下语句:

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

因此,我猜想它并没有删除对象本身,而只是取消了绑定。 但是,它在解除绑定方面做了什么工作,从而释放了很大的空间(152.6 MB)
。有人可以痛苦地解释我在这里发生什么吗?


问题答案:

Python是一种垃圾收集语言。如果您的代码中的值不再“可访问”,它将最终被删除。

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

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

如果有相同的值其它参考,但是,仅仅取消这些参考之一(无论是del xx = None在离开这里的范围x存在,等)不干净东西了。**

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

当Python释放存储空间时,它并不总是(甚至通常)将其返回给操作系统。它可以在多个级别上保留“空闲列表”,因此,与必须一直回到操作html" target="_blank">系统以请求更多资源相比,它可以更快地重用内存。在现代系统上,这几乎不成问题-
如果您再次需要存储,那么拥有它很好。如果您不这样做,它将在有人需要时立即被调出页面,并且永远不会被调回,因此几乎没有害处。

(最重要的是,我上面所说的“操作系统”实际上是由多个级别组成的抽象,从malloc库到核心C库再到内核/页面程序,这些级别中至少有一个通常具有它的拥有免费列表。)

如果您想从内部角度跟踪内存使用情况,那么……那很难。由于有了新tracemalloc模块,它在Python 3.4中变得容易得多。有各种第三方的模块(例如,heapy/
guppyPymplermeliae),尝试得到同样的与早期版本的信息,但是很难,因为从各个分配器获取信息,系该信息的垃圾收集器,非常在PEP
445之前努力。

*在某些情况下, 对价值的参考…但只能从自身是无法访问的,可能是在一个周期内其他的引用。就垃圾收集器而言,这仍然算作“无法到达”,但就引用计数而言,则算不上。因此,CPython还有一个“周期检测器”,它每隔一段时间运行一次,并从其他任何值中找到相互可访问但不可访问的周期,并进行清理。

**如果您正在交互式控制台中进行测试,则可能存在难以跟踪的隐藏引用,因此您可能会 认为 自己没有使用上一个引用。在脚本中,即使不是 很容易
,也应该总是 能够 解决问题。该模块可以提供帮助,调试器也可以提供帮助。不过,当然他们两个 给你新的方法来增加额外的隐藏引用。
gc



 类似资料:
  • 我很难理解的概念,因为根据视图,它做不同的事情。根据官方的留档,这是一个 用于根据系统窗口(如状态栏)调整视图布局的布尔内部属性。如果为true,则调整此视图的填充以为系统窗口留出空间。 现在,检查class我可以看到,当设置为时,窗口会插入(状态栏、导航栏…)应用于视图填充,该填充根据上面引用的文档工作。这是守则的相关部分: 有了新的材料设计,有了新的类别,这些类别广泛地使用了这面旗帜,这就是混

  • 问题内容: 我听说过很多有关Spring的信息,人们在网络上都说Spring是Web开发的良好框架。Spring Framework到底是做什么用的? 问题答案: 基本上,Spring是用于依赖项注入的框架,该框架是一种允许构建高度分离的系统的模式。 问题 例如,假设你需要列出系统的用户,从而声明一个名为的接口: 也许是一个访问数据库以获取所有用户的实现: 在你看来,你需要访问一个实例(仅作为示例

  • @basic(optional=false)@column(nullable=false)@basic注释将属性标记为Java对象级别的非可选属性。第二个设置,列映射上的nullable=false,只负责生成NOT NULL数据库约束。Hibernate JPA实现在任何情况下都以相同的方式对待这两个选项,因此您不妨只使用其中一个注释来实现这一目的。 我很困惑。这是什么意思-属性或变量在Java

  • 我很难理解流,以workcount为例,对于像Kafka这样的无限源,“sum”到底是做什么的? 我有点理解有时间窗的情况,因为它有开始和结束时间,对我来说就像一个“批次”,但如果没有时间窗, 什么是开始时间和结束时间

  • 问题内容: 在Tour of Go网站的go 1.5发行之前的版本中,有一段代码看起来像这样。 输出看起来像这样: 令我困扰的是,将其删除后,该程序不再显示“世界”。 为什么呢?如何影响执行力? 问题答案: 注意: 从Go 1.5开始,将GOMAXPROCS设置为硬件内核数:golang.org/doc/go1.5#runtime,低于1.5之前的原始答案。 当您在未指定GOMAXPROCS环境变