在开发环境中通常我们写python程序的时候也很少关注内存这个问题,可能写c和c++的朋友会更多的考虑这个问题,但是一旦我们的python程序出现了内存泄漏的问题,也将是一件非常麻烦的事情了,那么我们应该如何避免这类问题的发生,如果发生了我们该去如何解决的下面我们一起来看看吧!

起因

内存泄露指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。导致程序运行速度减慢甚至系统崩溃等严重后果。有 del() 函数的对象间的循环引用是导致内存泄漏的主凶

方案

不使用一个对象时使用:delobject 来删除一个对象的引用计数就可以有效防止内存泄漏问题。通过Python 扩展模块 gc 来查看不能回收的对象的详细信息。可以通过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0 来判断是否内存泄漏。

但是由于gc垃圾收集机制,要遍历所有被垃圾收集器管理的python对象(包括垃圾和非垃圾对象),该过程比较耗时可能会造成程序卡顿,会对某些对内存、cpu要求较高的场景造成性能影响。那怎么才能优雅地避免内存泄露呢?

编写安全的代码

比如对于下面发生内存泄露的cycle_ref函数,在函数结束前解除循环引用,即可解决内存泄露问题。

def cycle_ref():

a1 = A()a2 = A()a1.child = a2a2.child = a1# 解除循环引用,避免内存泄露a1.child  = Nonea2.child  = None

但是对于上述方法,我们有可能会忘记那一两行无关紧要的代码而造成灾难性后果,毕竟老虎也有打盹的时候。那怎么办?不要着急,Python已经为我们考虑到这点:弱引用。

弱引用

Python标准库提供了weakref模块,弱引用不会在引用计数中计数,其主要目的是解决循环引用。并非所有的对象都支持weakref,例如list和dict就不支持。下面是weakref比较常用的方法:

"""

  1. class weakref.ref(object[, callback]) :创建一个弱引用对象,object是被引用的对象,callback是回调函数(当被引用对象被删除时,调用该回调函数)

2.weakref.proxy(object[, callback]):创建一个用弱引用实现的代理对象,参数同上

3.weakref.getweakrefcount(object) :获取对象object关联的弱引用对象数

4.weakref.getweakrefs(object):获取object关联的弱引用对象列表

5.class weakref.WeakKeyDictionary([dict]):创建key为弱引用对象的字典

6.class weakref.WeakValueDictionary([dict]):创建value为弱引用对象的字典

7.class weakref.WeakSet([elements]):创建成员为弱引用对象的集合对象

"""

同样对于上面发生内存泄露的cycle_ref函数,使用weakref稍加改造,便可更安全地解决内存泄露问题:

import weakref

class A(object):

def __init__(self):    self.data = [x for x in range(100000)]    self.child = Nonedef __del__(self):    pass

def cycle_ref():

a1 = A()a2 = A()a1.child = weakref.proxy(a2)a2.child = weakref.proxy(a1)

if name == 'main':

import timewhile True:    time.sleep(0.5)    cycle_ref()
©著作权归作者所有:来自51CTO博客作者上海老男孩教育的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. Jquery基础知识
  2. 如何在 Java8 中风骚走位避开空指针异常
  3. mica-core 之常用工具类之$
  4. PHP多文件上传案和MVC简单案例以及MVC的依赖注入和服务容器的原
  5. 多文件上传、MVC依赖注入与服务容器
  6. 多文件上传-MVC依赖注入-容器管理依赖对象实现
  7. 你在 Python 中常常写的 with..as.. 到底是个啥?
  8. JVM垃圾回收机制
  9. 在聊Java中的equals方法

随机推荐

  1. 【python】通过代理安装包
  2. “全局变量是坏的”是什么意思?
  3. Python Django对接企业微信第三方服务回
  4. python 中的排序大法
  5. Python Flask WTForms:如何在视图中动态禁
  6. 从另一个Python脚本调用Python脚本的最佳
  7. python3如何打印进度条
  8. 基于fastai的分类网络
  9. 关于Python的编码注释# -*- coding:utf-8
  10. Python列表以及列表的处理方法