python清除变量
Ⅰ python 用del删除变量以后为什么还是OOM(Python的内存管理与垃圾回收)
本文使用 Zhihu On VSCode 创作并发布
目录:
一、前言 Preface
我一直以来没怎么认真学过python的内存释放机制,对于这东西总处于一种一知半解的情况。总以为我del 一个变量,那就自动在内存里删除了这个变量,自然而然地内存就被释放了。
然而,目前我工作刚满一年,在这一年的时光里,我遇到三四次无法理解的OOM错误,让我不得不认真的research一下单纯的del 到底能不能做到我想做的事。
我自己虽说一直有个读博的想法,但是在工作中为了效率,其实很多时候能用就行,并不用达到知其然,且知其所以然 的程度。所以我先调查到了一些问题出现的原因以及解决方法,最后再学习一下Python自己的内存回收机制。
Without further ado, let's start.二、实用正题 Practical part
从这篇博文 中,我们可以看到 必须要 import gc 然后用 gc.collect() 去回收已经 del 的大文件。在博文中,作者提到了用一个自定义函数清除环境中所有的全局变量。可能用得上,就转载记录到这里。
三、小学一点 Learn a little bit.python的内存管理方式
这是最新的Python-3.10 的关于内存管理的文档,文章长度很短,可以花两分钟阅读一下。(不过我也读不懂,或许应该读 gc 的文档)
准备知识: 关于变量与指向的对象
背景知识: from here
在编程中,程序的对象存储在内存中以供快速访问。在许多编程语言中,程序代码中的变量实际上只是一个指向内存中对象地址的指针。当变量被使用时,进程会从内存读取其值并对其进行操作。在早期的编程语言中,开发者需要手动管理程序的所有内存。这意味着在创建列表或对象之前,你需要先分配变量的内存。完成对变量的操作后,你需要释放内存,以便其他人使用。这导致了两个问题:忘记释放内存。如果不释放使用完毕的内存,会导致内存泄漏,导致程序随着时间的推移使用过多内存。过早释放内存。第二种类型的问题是过早释放仍然被使用的内存。这可能导致程序崩溃,因为它尝试访问不存在的内存值,或者可能导致数据损坏。引用一个已经释放内存的对象称为悬挂指针。
因此,现代语言中都采用了自动内存管理和垃圾回收机制。Python中采用以下策略实现内存回收。
3.1 引用计数 (Reference count)
在Python中,每个对象都有指向该对象的引用总数---引用计数
在Python中,每一个对象的核心是一个PyObject结构体,它包含一个引用计数器(ob_refcnt)。程序运行时实时更新这个计数器的值,反映当前对象被引用的数量。当对象的引用计数值为0,内存就会立即释放。查看对象引用计数的方法是使用sys.getrefcount()。
基本原理是,一个Python对象的引用计数在对象被引用时增加,在对象被引用解除时减少。当对象的引用计数为0,内存就被释放。
导致引用计数加一的情况:
导致引用计数减一的情况:
举例
引用计数的优点 (pros)
高效、实时,一旦一个对象的引用计数归零,内存就直接释放。无需等待特定时机,释放内存时间在程序运行过程中,程序运行比较平稳
引用计数的缺点 (cons)
虽然逻辑简单,但实现有些复杂。每个对象都需要分配单独的空间来统计引用计数,并需要维护这个计数
在某些情况下,可能会比较慢。通常垃圾回收平稳运行,但当需要释放大型对象时,如字典,需要对引用的所有对象进行嵌套循环调用,可能花费较长时间。
循环引用 (Circular References),这是引用计数难以解决的问题,需要使用其他垃圾回收算法进行补充。
3.2 标记清除 (Mark and Sweep)
Python采用“标记-清除”(Mark and Sweep)算法解决容器对象可能产生的循环引用问题。(注意,只有容器对象才会产生循环引用,如列表、字典、自定义类对象、元组等。数字、字符串等简单类型不会出现循环引用。作为一种优化策略,对于只包含简单类型的元组也不在标记清除算法的考虑之列)
循环引用示例
对于循环引用问题,比如两个对象互相引用对方,当它们各自没有其他引用(即引用计数都只有1),如果能识别出这个循环引用,将它们的计数减去,就可以看到它们的真实引用计数。为此,有一种方法,例如从对象A出发,沿着引用找到对象B,将B的引用计数减1;然后从B返回到A,将A的计数减1,这样可以去除这个循环引用关系。不过,还有一个需要考虑的地方。如果A只单向引用B,在找到B之前不知道B是否也引用A,先减去B的计数可能会让B成为不可回收的对象。为了解决这个问题,Python常将内存块一分为二,一部分用于保存真正的引用计数,另一部分用于引用计数副本,在副本上进行实验。例如,在副本中维护两个链表,一个放不可回收的对象集合,另一个放被标记为可以回收的对象(计数减为0),然后在后者中找一些被前者中对象直接或间接单向引用的对象,将它们移动到前者的表中。这样可以确保不应该被回收的对象不会被回收,应该被回收的对象都被回收。
3.3 分代回收 (Generational garbage collection)
这是一种以空间换取时间的方法。分代回收基于这样的统计事实:程序中存在一定比例的内存块生存周期较短;剩下的内存块,生存周期较长,甚至从程序开始到程序结束。生存期较短的对象比例通常在 80%~90% 之间。这种思想简单地说就是:对象存在时间越长,越可能是非垃圾,应该越少去收集。在执行标记-清除算法时,可以有效减少遍历的对象数,从而提高垃圾回收速度。Python gc给对象定义了三种世代(0,1,2),每一个新生对象在generation zero中,如果它在一轮gc扫描中活了下来,那么它将被移至generation one,在那里它将较少地被扫描,如果它又活过了一轮gc,它又将被移至generation two,在那里它被扫描的次数将会更少。gc的扫描触发时机是当某一世代中被分配的对象与被释放的对象之差达到某一阈值时。值得注意的是,当某一世代的扫描被触发时,比该世代年轻的世代也会被扫描。也就是说,如果世代2的gc扫描被触发,世代0,世代1也将被扫描;如果世代1的gc扫描被触发,世代0也会被扫描。
该阈值可以通过下面两个函数查看和调整:
常用函数:
如果垃圾回收不易理解,我们可以用现实生活中的例子来联想。开发商拍地,房管局登记开发商捂地的数量,增加或减少。这就是引用计数。如果地出现纠纷,陷入循环死结,政府会分别处理,各个击破。这就是标记-清除。如果开发商后台强大,捂地不开发,地方政府只能采取一贯做法,“让后代去解决”。这就是分代回收。关于set_threshold()中的三个参数threshold0, threshold1, threshold2的介绍:gc会记录自从上次收集以来新分配的对象数量与释放的对象数量,当两者之差超过threshold0的值时,gc的扫描就会启动,初始时只有世代0被检查。如果自从世代1最近一次被检查以来,世代0被检查超过 threshold_1 次,那么对世代1的检查将被触发。相同的,如果自从世代2最近一次被检查以来,世代1被检查超过 threshold_2 次,那么对世代2的检查将被触发。get_threshold()是获取三者的值,默认值为(700,10,10)。
Ⅱ 如何配置python的环境变量
如何配置Python的环境变量:
答案明确:
1. 打开系统设置。
2. 进入环境变量设置。
3. 新建系统环境变量,变量名为“PYTHONPATH”,变量值为Python安装路径。
4. 或者编辑Path环境变量,将Python安装路径添加到已有变量中。
详细解释:
步骤一:打开系统设置。
操作系统不同,打开系统设置的方式可能会有所不同。例如在Windows系统中,可以通过搜索“系统环境变量”来找到相关设置;在Linux或Mac系统中,则可以在终端使用特定命令来查看和编辑环境变量。
步骤二:进入环境变量设置。
环境变量是操作系统中用于指定操作系统运行环境的一些参数。在系统设置中,可以找到一个或多个与环境变量相关的选项。在Windows系统中,环境变量通常可以在“系统属性”下的“高级”选项卡中找到。
步骤三:配置Python环境变量。
有两种主要方式配置Python的环境变量。一种方式是新建系统环境变量,变量名为“PYTHONPATH”,这样可以让操作系统识别Python的安装路径。另一种方式是通过编辑Path环境变量,将Python的安装路径添加到已有的变量中。这样做的好处是可以在命令行直接运行Python及其脚本。
配置环境变量的具体步骤可能会因操作系统的不同而有所差异,但基本原理是相同的。按照上述步骤操作后,就可以成功配置Python的环境变量,从而方便在系统中运行Python程序。
Ⅲ 已知变量string=' python是一种解释型语言 '将变量string中的两侧空格去除并将字母'p'替换为大写字母'P'
给你写出来了,看一下
Ⅳ python怎么设置环境变量
Python设置环境变量的方法有多种,具体取决于你的操作系统和环境管理工具。以下是在不同操作系统上设置Python环境变量的常见方法:
一、在Windows上设置Python环境变量
1. 打开“我的电脑”或“此电脑”,右键点击“属性”。
2. 选择“高级系统设置”。
3. 在系统属性窗口中,点击“环境变量”按钮。
4. 在“系统变量”或“用户变量”部分,点击“新建”,然后添加你的Python环境变量。
二、在Linux或Mac上设置Python环境变量
1. 打开终端。
2. 使用export命令设置环境变量,例如:`export PYTHONPATH=/path/to/your/python/directory`。这将临时添加环境变量,当终端会话关闭后,环境变量将失效。
3. 若要永久设置环境变量,需要在shell的配置文件中添加export命令,然后重新加载配置文件或使用source命令使其立即生效。
详细解释:
在Windows系统中,环境变量是在系统属性中设置的,可以通过“高级系统设置”找到相关选项。在Linux和Mac系统中,环境变量通常在终端中使用export命令设置。值得注意的是,使用export命令设置的环境变量只在当前终端会话中有效,如果想要永久设置环境变量,需要在相应的配置文件中添加export命令并保存。这样,每次启动新的终端会话时,这些环境变量就会自动加载。
对于Python特定的环境变量,如PYTHONPATH,通常用于指定Python查找模块和包的路径。通过设置这些环境变量,可以影响Python的运行方式和行为。因此,在开发和运行过程中,根据需要设置合适的环境变量是非常重要的。