广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python 内存管理的工作原理,你了解吗?
  • 830
分享到

Python 内存管理的工作原理,你了解吗?

Python内存管理 2023-05-14 21:05:45 830人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

python 为开发者提供了许多便利,其中最大的便利之一是其几乎无忧的内存管理。开发者无需手动为 Python 中的对象和数据结构分配、跟踪和释放内存。运行时会为你完成所有这些工作,因此你可以专注于解决实际问题,而不是争论机器级细节。尽管如

python开发者提供了许多便利,其中最大的便利之一是其几乎无忧的内存管理。开发者无需手动为 Python 中的对象和数据结构分配、跟踪和释放内存。运行时会为你完成所有这些工作,因此你可以专注于解决实际问题,而不是争论机器级细节。

Python 内存管理的工作原理,你了解吗?

尽管如此,即使是经验不多的 Python 用户,了解 Python 的垃圾收集和内存管理是如何工作的也是有好处的。了解这些机制将帮助你避免更复杂的项目可能出现的性能问题。你还可以使用 Python 的内置工具监控程序的内存管理行为。

Python如何管理内存

每个 Python 对象都有一个引用计数,也称为引用计数。 refcount 是持有对给定对象的引用的其他对象总数的计数。当你添加或删除对对象的引用时,数字会上升或下降。当一个对象的引用计数变为零时,该对象将被释放并释放其内存。

什么是参考?允许通过名称或通过另一个对象中的访问器访问对象的任何内容。

这是一个简单的例子:

x = "Hello there"

当我们向 Python 发出这个命令时,引擎盖下会发生两件事:

  1. 字符串"Hello there"作为 Python 对象创建并存储在内存中。
  2. 该名称x在本地命名空间中创建并指向该对象,这会将其引用计数增加 1 到 1。

如果我们说y = x,那么引用计数将再次提高到 2。

每当xandy超出范围或从它们的命名空间中删除时,对于每个名称,字符串的引用计数都会减少 1。一旦x和y都超出范围或被删除,字符串的引用计数变为 0 并被删除。

现在,假设我们创建了一个包含字符串的列表,如下所示:

x = ["Hello there", 2, False]

字符串保留在内存中,直到列表本身被删除或包含字符串的元素从列表中删除。这些操作中的任何一个都将导致唯一持有对字符串的引用的事物消失。

现在考虑这个例子:

x = "Hello there" y = [x]

如果我们从 中删除第一个元素y,或者完全删除列表y,则字符串仍在内存中。这是因为名称x包含对它的引用。

Python 中的引用循环

在大多数情况下,引用计数工作正常。但有时你会遇到两个对象各自持有对彼此的引用的情况。这称为 参考周期。在这种情况下,对象的引用计数永远不会达到零,也永远不会从内存中删除。

这是一个人为的例子:

x = SomeClass()
y = SomeOtherClass()
x.item = y
y.item = x

由于x并y持有彼此的引用,因此它们永远不会从系统中删除——即使没有其他任何东西引用它们中的任何一个。

Python 自己的运行时为对象生成引用循环实际上是相当普遍的。一个示例是带有包含对异常本身的引用的回溯对象的异常。

在Python的早期版本中,这是一个问题。具有引用周期的对象可能会随着时间的推移而累积,这对于长时间运行的应用程序来说是一个大问题。但 Python 此后引入了循环检测和垃圾收集系统,用于管理引用循环。

Python 垃圾收集器 (GC)

Python 的垃圾收集器检测具有引用周期的对象。它通过跟踪作为“容器”的对象(例如列表、字典、自定义类实例)并确定其中的哪些对象无法在其他任何地方访问来实现这一点。

一旦这些对象被挑选出来,垃圾收集器就会通过确保它们的引用计数可以安全地降为零来删除它们。

绝大多数 Python 对象没有引用周期,因此垃圾收集器不需要 24/7 运行。相反,垃圾收集器使用一些启发式方法来减少运行频率,并且每次都尽可能高效地运行。

当 Python 解释器启动时,它会跟踪已分配但未释放的对象数量。绝大多数 Python 对象的生命周期都很短,因此它们会迅速出现和消失。但随着时间的推移,更多长寿的物体会出现。一旦超过一定数量的此类对象堆积起来,垃圾收集器就会运行。

每次垃圾收集器运行时,它都会收集所有在收集中幸存下来的对象,并将它们放在一个称为一代的组中。这些“第一代”对象在参考周期中被扫描的频率较低。任何在垃圾收集器中幸存下来的第一代对象最终都会迁移到第二代,在那里它们被扫描得更少。

同样,垃圾收集器不会跟踪所有内容。例如,像用户创建的类这样的复杂对象总是被跟踪。但是不会跟踪仅包含简单对象(如整数和字符串)的字典,因为该特定字典中的任何对象都不会包含对其他对象的引用。不能保存对其他元素(如整数和字符串)的引用的简单对象永远不会被跟踪。

如何使用 gc 模块

通常,垃圾收集器不需要调整即可运行良好。Python 的开发团队选择了反映最常见现实世界场景的默认值。但是如果你确实需要调整垃圾收集的工作方式,你可以使用Python 的 gc 模块。该gc模块为垃圾收集器的行为提供编程接口,并提供对正在跟踪的对象的可见性。

gc当你确定不需要垃圾收集器时,你可以做的一件有用的事情是关闭它。例如,如果你有一个堆放大量对象的短运行脚本,则不需要垃圾收集器。脚本结束时,所有内容都将被清除。为此,你可以使用命令禁用垃圾收集器gc.disable()。稍后,你可以使用 重新启用它gc.enable()。

你还可以使用 手动运行收集周期gc.collect()。一个常见的应用是管理程序的性能密集型部分,该部分会生成许多临时对象。你可以在程序的该部分禁用垃圾收集,然后在最后手动运行收集并重新启用收集。

另一个有用的垃圾收集优化是gc.freeze(). 发出此命令时,垃圾收集器当前跟踪的所有内容都被“冻结”,或者被列为免于将来的收集扫描。这样,未来的扫描可以跳过这些对象。如果你有一个程序在启动之前导入库并设置大量内部状态,那么你可以gc.freeze()在所有工作完成后发出。这使垃圾收集器不必搜寻那些无论如何都不太可能被删除的东西。(如果你想对冻结的对象再次执行垃圾收集,请使用gc.unfreeze().)

使用 gc 调试垃圾收集

你还可以使用它gc来调试垃圾收集行为。如果你有过多的对象堆积在内存中并且没有被垃圾收集,你可以使用gc's 检查工具来找出可能持有对这些对象的引用的对象。

如果你想知道哪些对象持有对给定对象的引用,可以使用gc.get_referrers(obj)列出它们。你还可以使用gc.get_referents(obj)来查找给定对象引用的任何对象。

如果你不确定给定对象是否是垃圾收集的候选对象,gc.is_tracked(obj)请告诉你垃圾收集器是否跟踪该对象。如前所述,请记住垃圾收集器不会跟踪“原子”对象(例如整数)或仅包含原子对象的元素。

如果你想亲自查看正在收集哪些对象,可以使用 设置垃圾收集器的调试标志gc.set_debug(gc.DEBUG_LEAK|gc.DEBUG_STATS)。这会将有关垃圾收集的信息写入stderr。它将所有作为垃圾收集的对象保留在只读列表中。

避免 Python 内存管理中的陷阱

如前所述,如果你在某处仍有对它们的引用,则对象可能会堆积在内存中而不会被收集。这并不是 Python 垃圾收集本身的失败。垃圾收集器无法判断你是否不小心保留了对某物的引用。

让我们以一些防止对象永远不会被收集的指针作为结尾。

注意对象范围

如果你将对象 1 指定为对象 2 的属性(例如类),则对象 2 将需要超出范围,然后对象 1 才会:

obj1 = MyClass()
obj2.prop = obj1

更重要的是,如果这种情况发生在某种其他操作的副作用中,例如将对象 2 作为参数传递给对象 1 的构造函数,你可能不会意识到对象 1 持有一个引用:

obj1 = MyClass(obj2)

另一个例子:如果你将一个对象推入模块级列表并忘记该列表,则该对象将一直保留,直到从列表中删除,或者直到列表本身不再有任何引用。但是如果该列表是一个模块级对象,它可能会一直存在,直到程序终止。

简而言之,请注意你的对象可能被另一个看起来并不总是很明显的对象持有的方式。

使用 weakref避免引用循环

Python 的 weakref 模块允许你创建对其他对象的弱引用。弱引用不会增加对象的引用计数,因此只有弱引用的对象是垃圾回收的候选对象。

一个常见的用途weakref是对象缓存。你不希望仅仅因为它具有缓存条目而保留引用的对象,因此你将 aweakref用于缓存条目。

手动中断参考循环

最后,如果你知道给定对象包含对另一个对象的引用,你总是可以手动中断对该对象的引用。例如,如果你有instance_of_class.ref = other_object,你可以设置instance_of_class.ref = None何时准备删除 instance_of_class。

通过了解 Python 内存管理的工作原理,我们对其垃圾收集系统如何帮助优化 Python 程序中的内存,以及如何使用标准库和其他地方提供的模块来控制内存使用和垃圾收集。

原文标题:​​Python garbage collection and the gc module​​

以上就是Python 内存管理的工作原理,你了解吗?的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: Python 内存管理的工作原理,你了解吗?

本文链接: https://www.lsjlt.com/news/205507.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python 内存管理的工作原理,你了解吗?
    Python 为开发者提供了许多便利,其中最大的便利之一是其几乎无忧的内存管理。开发者无需手动为 Python 中的对象和数据结构分配、跟踪和释放内存。运行时会为你完成所有这些工作,因此你可以专注于解决实际问题,而不是争论机器级细节。尽管如...
    99+
    2023-05-14
    Python 内存管理
  • 你了解Python响应文件框架的工作原理吗?
    Python是一种高级编程语言,它被广泛用于Web开发、数据分析、机器学习等领域。Python的一个重要特性是其丰富的库和框架,其中之一就是响应文件框架。这个框架非常有用,因为它可以帮助我们处理HTTP请求和响应,本文将介绍Python响应...
    99+
    2023-07-20
    响应 文件 框架
  • 你真的了解Python日志打包load的工作原理吗?
    Python是一门广泛应用于各种领域的编程语言。在日志处理方面,Python也提供了很多的库和工具。其中,日志打包和load是日志处理中常用的操作之一。本文将深入讲解Python中日志打包和load的工作原理,并演示一些实用的代码。 一、日...
    99+
    2023-10-29
    日志 打包 load
  • C++的动态内存管理你真的了解吗
    目录前言用法上对内置类型对自定义类型new/delete底层原理重载类的专属operator new和 operator delete定位newnew/delete与malloc/f...
    99+
    2022-11-13
  • C语言的动态内存管理你了解吗
    目录C/C++内存分配方式C++内存管理方式new和delete的使用new和delete的骚操作new和delete的区别重载new和delete定位new表达式内存泄露总结C/C...
    99+
    2022-11-13
  • Python异步编程,你是否了解IDE缓存的工作原理?
    随着现代应用程序的复杂性不断增加,异步编程模型在Python编程中变得越来越流行。异步编程的主要目的是提高代码的并发性和性能。它可以允许多个任务同时执行,并且不会阻塞主线程。这篇文章将探讨Python异步编程中的IDE缓存工作原理,并提供...
    99+
    2023-08-24
    异步编程 ide 缓存
  • C/C++的内存管理你了解嘛
    目录C/C++内存分布C语言中动态内存管理方式C++ 内存管理方式new和delete操作自定义类型new和delete的实现原理1.内置类型2.自定义类型malloc/free和n...
    99+
    2022-11-13
  • Python内存管理的原理
    这篇文章主要介绍“Python内存管理的原理”,在日常操作中,相信很多人在Python内存管理的原理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python内存管理的原理”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-15
  • 你了解 Java 对象在 HTTP 加载时的工作原理吗?
    Java 对象在 HTTP 加载时的工作原理 在 Java 中,对象是一种非常重要的概念。随着 Web 技术的发展,HTTP 协议成为了 Web 应用程序中最常用的协议之一。在 Web 应用程序中,Java 对象在 HTTP 加载时的工作原...
    99+
    2023-07-27
    对象 http load
  • PHP 对象容器和 Shell:你了解它们的工作原理吗?
    在 PHP 中,对象容器和 Shell 是两个非常重要的概念。本文将介绍它们的工作原理,并演示一些代码示例。 对象容器 对象容器是一个用于存储和管理对象的容器。在 PHP 中,我们可以使用 SPL(标准 PHP 库)中的 ArrayObj...
    99+
    2023-06-23
    对象 容器 shell
  • Spring的事务管理你了解吗
    目录1、事务介绍2、事务的四个特性(ACID)3、Spring 事务管理的核心接口4、PlatformTransactionManager 事务管理器5、TransactionSta...
    99+
    2022-11-13
  • Python中的内存管理的原理是什么?
    Python中的内存管理的原理是什么?Python是一种高级的、动态类型的编程语言,具有自动垃圾回收功能。Python内存管理的原理基于引用计数机制和垃圾回收机制。引用计数机制是Python内存管理的基础。每个对象都会有一个引用计数器,用于...
    99+
    2023-10-22
    内存管理原理 Python内存管理 内存分配策略
  • 怎么理解Python的内存管理
    这篇文章主要介绍“怎么理解Python的内存管理”,在日常操作中,相信很多人在怎么理解Python的内存管理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解Python的内存管理”的疑惑有所帮助!接下来...
    99+
    2023-06-01
  • Vue的diff算法原理你真的了解吗
    目录思维导图0. 从常见问题引入1. 生成虚拟dom1. h方法实现2. render方法实现3. 再次渲染2. diff算法1. 对常见的dom做优化情况1:末尾追加一个元素(头和...
    99+
    2022-11-13
  • Python内存管理机制的原理是什么
    今天就跟大家聊聊有关Python内存管理机制的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。小块空间的内存池在Python中,许多时候申请的内存都是小块的内存,这些小块内存...
    99+
    2023-06-17
  • Java内存的原型及工作原理是什么
    这篇文章给大家介绍Java内存的原型及工作原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。主要通过分析Java内存分配的栈、堆以以及常量池详细的讲解了其的工作原理。一、java虚拟机内存原型寄存器:我们在程序中...
    99+
    2023-06-17
  • Laravel 开发者必须了解 ASP 容器的工作原理吗?
    Laravel 是一个流行的 PHP 开发框架,许多开发者都喜欢使用它来构建高质量的 Web 应用程序。但是,当涉及到 ASP 容器时,许多 Laravel 开发者可能并不了解其工作原理。那么,Laravel 开发者是否必须了解 ASP 容...
    99+
    2023-09-30
    容器 关键字 laravel
  • 您是否了解ASP存储接口shell的工作原理?
    ASP存储接口shell是一种在ASP程序中使用的存储接口,它可以让开发者更加方便地进行文件操作和存储。本文将介绍ASP存储接口shell的工作原理,以及如何使用它进行文件操作和存储。 一、ASP存储接口shell的工作原理 ASP存储接口...
    99+
    2023-11-06
    存储 接口 shell
  • 计算机内存的工作原理是什么
    计算机内存的工作原理是:内存寻址内存可以从CPU获得查找某个数据的指令,在找出存取资料的位置,其会先定出横坐标,在定出纵坐标。内存传输当储存资料或从内存内部读取资料时,CPU会通过地址总线将地址送到内存,后由数据总线将对应的数据传输到微处理...
    99+
    2022-10-17
  • 【JavaEE】简单了解操作系统、进程&内存管理
    目录 前言:  一、操作系统: 操作系统的定位: 应用程序: 系统调用: 操作系统内核: 驱动程序: 硬件设备:  二、进程:  什么是进程?  进程的描述与组织:  描述: 组织: PCB中的 特征(属性) CPU分配——进程调度:  进...
    99+
    2023-09-02
    运维 服务器 java linux java-ee
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作