谈谈如何手动释放Python的内存_python

在上篇博客中,提到了对一个脚本进行的多次优化。当时以为已经优化得差不多了,但是当测试人员测试时,我才发现,踩到了Python的一个大坑。

在上文的优化中,对每500个用户,会进行一些计算并记录结果在磁盘文件中。原本以为这么做,这些结果就在磁盘文件中了,而不会再继续占用内存;但实际上,Python的大坑就是Python不会自动清理这些内存。这是由其本身实现决定的。具体原因网上多有文章介绍,这里就不copy了。

本篇博客将贴一个笔者的实验脚本,用以说明Python确实存在这么一个不释放内存的现象,另外也提出一个解决方案,即:先del,再显式调用gc.collect(). 脚本和具体效果见下。

实验环境一:Win 7, Python 2.7

from time import sleep, time
import gc 

def mem(way=1):
 print time()
 for i in range(10000000):
  if way == 1:
   pass
  else: # way 2, 3
   del i 

 print time()
 if way == 1 or way == 2:
  pass
 else: # way 3
  gc.collect()
 print time() 

if __name__ == "__main__":
 print "Test way 1: just pass"
 mem(way=1)
 sleep(20)
 print "Test way 2: just del"
 mem(way=2)
 sleep(20)
 print "Test way 3: del, and then gc.collect()"
 mem(way=3)
 sleep(20) 

运行结果如下:

Test way 1: just pass
1426688589.47
1426688590.25
1426688590.25
Test way 2: just del
1426688610.25
1426688611.05
1426688611.05
Test way 3: del, and then gc.collect()
1426688631.05
1426688631.85
1426688631.95 

对于way 1和way 2,结果是完全一样的,程序内存消耗峰值是326772KB,在sleep 20秒时,内存实时消耗是244820KB;

对于way 3,程序内存消耗峰值同上,但是sleep时内存实时消耗就只有6336KB了。

实验环境二: Ubuntu 14.10, Python 2.7.3

运行结果:

Test way 1: just pass
1426689577.46
1426689579.41
1426689579.41
Test way 2: just del
1426689599.43
1426689601.1
1426689601.1
Test way 3: del, and then gc.collect()
1426689621.12
1426689622.8
1426689623.11 
ubuntu@my_machine:~$ ps -aux | grep test_mem
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
ubuntu 9122 10.0 6.0 270916 245564 pts/1 S+ 14:39 0:03 python test_mem.py
ubuntu 9134 0.0 0.0 8104 924 pts/2 S+ 14:40 0:00 grep --color=auto test_mem
ubuntu@my_machine:~$ ps -aux | grep test_mem
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
ubuntu 9122 10.0 6.0 270916 245564 pts/1 S+ 14:39 0:03 python test_mem.py
ubuntu 9134 0.0 0.0 8104 924 pts/2 S+ 14:40 0:00 grep --color=auto test_mem
ubuntu@my_machine:~$ ps -aux | grep test_mem
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html
ubuntu 9122 11.6 0.1 30956 5608 pts/1 S+ 14:39 0:05 python test_mem.py 

结论:

以上说明,当调用del时,其实Python并不会真正release内存,而是将其继续放在其内存池中;只有在显式调用gc.collect()时,才会真正release内存。

进一步:

其实回到上一篇博客的脚本中,也让其引入gc.collect(),然后写个监控脚本监测内存消耗情况:

while ((1)); do ps -aux | sort -n -k5,6 | grep my_script; free; sleep 5; done 

结果发现:内存并不会在每500个用户一组执行完后恢复,而是一直持续消耗到仅存约70MB时,gc才好像起作用。本环境中,机器使用的是Cloud instance,总内存2G,可用内存约为1G,本脚本内存常用消耗是900M - 1G。换句话说,对于这个脚本来说,gc并没有立即起作用,而是在系统可用内存从1 - 1.2G下降到只剩70M左右时,gc才开始发挥作用。这点确实比较奇怪,不知道和该脚本是在Thread中使用的gc.collect()是否有关,或者是gc发挥作用原本就不是可控的。笔者尚未做相关实验,可能在下篇博客中继续探讨。

但是,可以肯定的是,若不使用gc.collect(), 原脚本将会将系统内存耗尽而被杀死。这一点从syslog中可以明显看出。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索python
, 内存释放
手动释放内存
python 手动释放内存、python 内存释放、python 释放变量内存、python 强制释放内存、python如何释放内存,以便于您获取更多的相关知识。

时间: 2024-10-27 06:17:54

谈谈如何手动释放Python的内存_python的相关文章

手动释放Linux服务器内存(具体操作步骤)_unix linux

在服务器运行过程中,使用free -m查看服务器内存时,经常会发现free值很小,有些同学就会很紧张,总想采取一些措施,使得free值看起来高一点,心里就比较爽一点.其实,个人觉得这完全是图一时之快,没什么实质性用途. 一.大众释放内存方法1. 首先使用free -m查看剩余内存 复制代码 代码如下: linux-8v2i:~ # free -m             total       used       free     shared    buffers     cachedMem

手动释放linux内存cache

总有很多朋友对于Linux的内存管理有疑问,之前一篇linux下的内存管理方式似乎也没能清除大家的疑虑.而在新版核心中,似乎对这个问题提供了新的解决方法,特转出来给大家参考一下.最后,还附上我对这方法的意见,欢迎各位一同讨论. 当在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching.这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法.那么我来谈谈这个问题. 一.通常情况 先来说说free命令: # free -m total

Python深入06——python的内存管理详解_python

语言的内存管理是语言设计的一个重要方面.它是决定语言性能的重要因素.无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征.这里以Python语言为例子,说明一门动态类型的.面向对象的语言的内存管理方式. 对象的内存使用 赋值语句是语言最常见的功能了.但即使是最简单的赋值语句,也可以很有内涵.Python的赋值语句就很值得研究. a = 1 整数1为一个对象.而a是一个引用.利用赋值语句,引用a指向对象1.Python是动态类型的语言(参考动态类型),对象与引用分离.Python

从Python的源码浅要剖析Python的内存管理_python

Python 的内存管理架构(Objects/obmalloc.c): 复制代码 代码如下:     _____   ______   ______       ________    [ int ] [ dict ] [ list ] ... [ string ]       Python core         | +3 | <----- Object-specific memory -----> | <-- Non-object memory --> |     _____

浅谈Python 对象内存占用_python

一切皆是对象 在 Python 一切皆是对象,包括所有类型的常量与变量,整型,布尔型,甚至函数. 参见stackoverflow上的一个问题 Is everything an object in python like ruby 代码中即可以验证: # everythin in python is object def fuction(): return print isinstance(True, object) print isinstance(0, object) print isinst

Python深入06 Python的内存管理

原文:Python深入06 Python的内存管理 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   语言的内存管理是语言设计的一个重要方面.它是决定语言性能的重要因素.无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征.这里以Python语言为例子,说明一门动态类型的.面向对象的语言的内存管理方式.   对象的内存使用 赋值语句是语言最常见的功能了.但即使是最简单的赋值语句,也可以很有内涵.Python

PHPer请手动释放你的资源

我从来不认为这个问题是个问题, 直到昨天. 昨天晚上的时候, 我提交了一个RFC, 关于引入finally到PHP, 实现这个功能的出发点很简单, 因为我看见不少人的需求, 另外还有就是Stas说, 一直只看到讨论, 没看到有人实现. 于是我就给实现了. 发到邮件组以后, 一个开发组的同学Nikita Popov(nikic), 表示强烈反对这个RFC, 当然最初的论点他说了很多, 最后我们在线讨论的时候, 他表达了一个他的观点: "PHP在请求结束后会释放所有的资源, 所以我们没有必要调用fc

实现释放CentOS系统内存的Shell脚本分享_linux shell

这几天发现CentOS系统内存一直涨,即使把apache和mysql关闭了,内存也不释放,可以使用以下脚本来释放内存:   脚本内容:   复制代码 代码如下:     #! /bin/bash       # cache释放:       # To free pagecache:       sync       sync       #echo 1 > /proc/sys/vm/drop_caches       # To free dentries and inodes:       #e

Python 检测内存使用量代码实例

去年时,自己写一个程序时,不太确定自己的内存使用量,就想找写工具来打印程序或函数的内存使用量. 这里将上次找到的内存检测工具的基本用法记录一下,今后分析Python程序内存使用量时也是需要的.这里推荐2个工具吧. memory_profiler模块(与psutil一起使用) 注:psutil这模块,我太喜欢了,它实现了很多Linux命令的主要功能,如:ps, top, lsof, netstat, ifconfig, who, df, kill, free 等等. 示例代码(https://gi