c 如何修改python释放变量内存3 变量的内存?

在以下示例中我有一些有关内存使用的相关问题。

  • 如果我在解释器中运行

我的机器上使用的实际内存最高为80.9mb。那我

实际内存下降但仅限于30.4mb。解释器使用4.4mb基线因此鈈26mbOS 释放内存有什么好处?是否因为python释放变量内存正在“提前计划”以为你可能会再次使用那么多的内存?

  1. 它为什么50.5mb特别释放- 释放的量基于什么

  2. 有没有一种方法可以强制python释放变量内存释放所有已使用的内存(如果你知道不会再使用那么多的内存)?

注意 此问题不同于我洳何在python释放变量内存中显式释放内存 因为这个问题主要解决了内存使用量相对于基线的增加,即使解释器通过垃圾回收(使用gc.collect或不使用)释放了对象之后

堆上分配的内存可能会出现高水位标记。python释放变量内存 PyObject_Malloc在4个KiB池中分配小对象()的内部优化使情况复杂化分类为8字節倍数的分配大小-最多256字节(3.3中为512字节)。池本身位于256 KiB竞技场中因此,如果仅在一个池中使用一个块则不会释放整个256 KiB竞技场。在python释放變量内存 3.3中小型对象分配器已切换为使用匿名内存映射而不是堆,因此它在释放内存方面应表现更好

此外,内置类型维护以前分配的對象的空闲列表这些对象可能使用也可能不使用小对象分配器。该int类型维护一个具有自己分配的内存的空闲列表要清除它,需要调用PyInt_ClearFreeList()可以通过做一个full来间接地调用它gc.collect

我改用相对于进程VM大小的度量来消除系统中其他进程的影响

当顶部的连续可用空间达到恒定,动态戓可配置的阈值时C运行时(例如glibc,msvcrt)会缩小堆使用glibc,你可以使用mallopt(M_TRIM_THRESHOLD)进行调整鉴于此,如果堆的收缩量比你的块减少的量更大甚臸更多,也就不足为奇了free

3.x range中不会创建列表,因此上面的测试不会创建1000万个int对象即使这样做,int3.x中的类型也基本上是2.x long它没有实现自由列表。

有没有一种方法可以强制python释放变量内存释放所有已使用的内存(如果你知道不会再使用那么多的内存)

不,那里没有但是有一個简单的解决方法:子进程。

如果需要5分钟的500MB临时存储但是之后又需要运行2个小时,并且不会再碰到那么多的内存请生成一个子进程來进行占用大量内存的工作。当子进程消失时内存将被释放。

这不是完全琐碎和免费的但是它很容易且便宜,通常足以使交易值得

洳果需要更多控制,请使用该multiprocessing模块

  • 在某些平台上,尤其是Windows进程启动有点慢。我们在这里以毫秒为单位而不是分钟,如果你要让一个駭子做300秒的工作你甚至不会注意到。但这不是免费的
  • 如果使用大量的临时存储的还真是大,这样做可能会导致换出你的主程序当然,从长远来看你可以节省时间,因为如果该内存永远存在那将导致在某些时候进行交换。但是在某些使用情况下,这可能会将逐渐嘚缓慢转变为非常明显的一次(和早期)延迟
  • 在进程之间发送大量数据可能很慢。同样如果你正在谈论发送超过2K的参数并返回64K的结果,你甚至不会注意到它但是如果你发送和接收大量数据,则需要使用其他某种机制(文件mmapPed或其他格式;共享内存API multiprocessing;等)。
  • 在进程之间發送大量数据意味着数据必须是可腌制的(或者如果将它们粘贴到文件或共享内存中,struct则是-理想情况下是-理想的ctypes

与本文内容配套的图书:《跟老齊学python释放变量内存:轻松入门》《python释放变量内存大学实用教程》各大电商平台有售。


python释放变量内存中的is==是不一样的使用is可以比较数芓,代码也正常运行也有人说is==要更快,或者你可能觉得它看起来更像python释放变量内存然而,重要的是要记住这些运算符的行为并不完铨相同

==用于比较两个对象的值是否相等,而is检查两个变量是否指向内存中的同一个对象在大多数情况下,这意味着你应该使用==!=除非与None进行比较。

  • 对象相等和同一性的区别是什么
  • 何时使用==is比较对象
  • 这些python释放变量内存运算符的原理是什么
  • 为什么使用isis not比较值会导致意外
  • 如何编写自定义的__eq__()类方法来定义相等运算符行为

isis not用来比较两个对象在Cpython释放变量内存中,比较的是对象的内存地址python釋放变量内存中的一切都是对象,每个对象都存储在特定的内存位置 isis not‘检查两个变量是否引用内存中的同一个对象。

注意: 记住具有楿同值的对象可能存储在不同的内存地址中。

你可以使用id() 来检查一个对象的内存地址:

 

最后一行显示存储内置函数id本身的内存地址

通常,具有相同值的对象在默认情况下具有相同的id例如,数字-5到256在Cpython释放变量内存中被保存每个数字都存储在内存中单一且固定的位置,这为瑺用整数节省了内存

你可以使用sys.intern()来保存字符串以提高性能,此函数允许你比较它们的内存地址而不是对字符串里的字符进行逐个比较:

 
 

变量ab最初指向内存中的两个不同对象,如它们的不同id所示使用intern后,ab则指向内存中的同一对象在原来的操作中,两个'hello world'分别在新的內存位置创建对象但是,对同样的字符串执行intern后后面所创建的字符串所指向的内存地址与第一个'hello world'的内存地址相同。

注意:即使对象的內存地址在任何给定的时间都是唯一的但这个内存地址在同一代码的不同运行过程中是不同的,并且取决于Cpython释放变量内存的版本和运行玳码的计算机

默认情况下,具有intern效果的对象是NoneTrueFalse和简单字符串请记住,大多数情况下具有相同值的不同对象将存储在不同的内存哋址中,这意味着你不应该使用is来比较值

python释放变量内存将常用的值(例如,整数-5到256)默认保存在内存中从而节省内存开支。丅面的代码向你展示了为什么只有一些整数具有固定的内存地址:

 
 

最初ab引用内存中的同一个存储对象,但当它们的值超出常用整数的范围(从-5到256)时它们就存储在不同的内存地址中。

当多个变量引用同一对象时

用赋值运算符(=)使一个变量等于另一个变量时可以使这些变量指向内存中的同一对象。这可能会导致可变对象出现意外行为:

 
 

刚才发生了什么? 你向a 添加了一个新元素但是现在b也包含了这个元素! 在b = a这一行,设置b指向与a相同的内存地址这样两个变量就都引用相同的对象。

如果你独立地定义这些列表那么它们就被存储在不同的内存地址中,并独立地运行:

 

因为ab现在引用内存中的不同对象所以更改一个对象不会影响另一个对象。

回想一下具有相同值的对象通常存储在不同的内存地址中。如果要检查两个对象是否具有相同的值而不管它们存储在内存Φ的位置,使用运算符=!=在绝大多数情况下,这就是你想做的

当对象副本相等但不相同时

在下面的示例Φ,ba的副本(a是可变对象如列表或字典)。两个变量都有相同的值但它们将各自存储在不同的内存地址:

 
 

ab 现在存储在不同的内存哋址,因此a is b不再返回True但是,a==b返回True因为两个对象具有相同的值。

==的魔力体现在该符号左边对象所具有的__eq__()方法中

这昰一个神奇的类方法,每当这个类的一个实例与另一个对象进行比较时都会调用它如果未实现此方法,则默认情况下==比较两个对象的内存地址

作为练习,创建一个继承strSillyString类并实现__eq__() 以比较此字符串的长度是否与另一个对象的长度相同:

 
 
 

当然,对于一个字符串形式的对象來说这是愚蠢的行为,但它确实说明了当你使用==比较两个对象时会发生什么对于!=,则是通过实现特定的__ne__()方法给出逆响应。

上面的示唎还清楚地向你展示了为什么更好的做法是用 is来比较None而不是使用==运算符。is比较的是内存地址所以它不仅更快,而且更安全因为它不依赖于任何__eq__()方法的逻辑。

根据经验你应该常用==!=,除非与None进行比较:

  • 使用==!=比较对象的相等性这里,你通常比较两个對象的值如果要比较两个对象是否具有相同的内容,而不关心它们存储在内存中的位置则需要下面的做法。
  • 如果要比较对象的唯一标識请使用isis not。这里你要比较两个变量是否指向内存中的同一个对象。这些运算符的主要用例是与None进行比较与使用类方法相比,按内存地址与None进行比较更快、更安全

具有相同值的变量通常存储在不同的内存地址中,这意味着你应该使用==!=来比较他们的值只有当你想检查两个变量是否指向同一个内存地址时,才使用isis not

在本文中,你了解了==!=比较两个对象的值而isis not比较两个变量是否引用内存中的同一个对象。如果你牢记这一区别那么应该能够防止代码中出现意外行为。

你还可以看看如何使用sys.intern()来优化字符串的内存使用和比較尽管python释放变量内存可能已经在幕后自动为你处理了这一问题。

现在你已经了解了两种比较的幕后操作可以尝试编写自己的__eq__()方法,这些方法定义了在使用==运算符时如何比较该类的实例去应用关于python释放变量内存比较运算符的这些新知识吧!

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

关注微信公众号免费获得在线机器学习案例

我要回帖

更多关于 python释放变量内存 的文章

 

随机推荐