Python内存泄漏和内存溢出的解决方法

发布时间:2020-10-30 23:08:34

来源:亿速云

阅读:92

作者:Leah

这篇文章将为大家详细讲解有关Python内存泄漏和内存溢出的解决方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

一、内存泄漏

像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题。

对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”。

1、内存泄露的原因

对于 python 这种支持垃圾回收的语言来说,怎么还会有内存泄露? 概括来说,有以下三种原因:所用到的用 C 语言开发的底层模块中出现了内存泄露。

代码中用到了全局的 list、 dict 或其它容器,不停的往这些容器中插入对象,而忘记了在使用完之后进行删除回收

代码中有“引用循环”,并且被循环引用的对象定义了__del__方法,就会发生内存泄露。

为什么循环引用的对象定义了__del__方法后collect就不起作用了呢?

gc模块最常使用的方法就是gc.collect()方法,使用collect方法对循环引用的对象进行垃圾回收。

如果我们在类中重载了__del__方法。__del__方法定义了在用del语句删除对象时除了释放内存空间以外的操作。

一般而言,在使用了del语句的时候解释器首先会看要删除对象的引用计数,如果为0,那么就释放内存并执行del方法。

在这里,首先del语句出现时本身引用计数就不为0(因为有循环引用的存在),所以解释器不释放内存;

再者,执行collect方法时应该会清除循环引用所产生的无效引用计数从而达到del的目的,对于这两个循环引用对象而言,

python无法判断调用它们的del方法时会不会要用到对方那个对象,比如在进行b.del()时可能会用到b._a也就是a,如果在那之前a已经被释放,那么就彻底GG了。

为了避免这种情况,collect方法默认不对重载了del方法的循环引用对象进行回收,而它们俩的状态也会从unreachable转变为uncollectable。由于是uncollectable的,自然就不会被collect处理,所以就进入了garbage列表。

2、内存泄露的诊断思路

无论是哪种方式的内存泄露,最终表现的形式都是某些 python 对象在不停的增长;因此,首先是要找到这些异常的对象。

3、诊断步骤

用到的工具: gc 模块和 objgraph 模块

gc模块 是Python的垃圾收集器模块,gc使用标记清除算法回收垃圾

objgraph 是一个用于诊断内存问题的工具1、 在服务程序的循环逻辑中,选择出一个诊断点

2、 在诊断点,插入如下诊断语句

import gc

import objgraph

### 强制进行垃圾回收

gc.collect()

### 打印出对象数目最多的 50 个类型信息

objgraph.show_most_common_types(limit=50)

4、检查统计信息,找到异常对象

运行加入诊断语句的服务程序,并将打印到屏幕上的统计信息重定向到日志中。运行一段时间后,就可以来分析日志,看看哪些对象在不停的增长。

比如,排查结果可能是:

一个多线程程序,多个线程作为生产者,一个线程作为消费者,通过将一个 tuple 对象送入异步队列进行通信。

由于消费者的处理速度跟不上生产者的速度,又没有进行同步, 导致异步队列中的对象越来越多。

二、内存溢出

1、内存溢出原因内存中加载的数据量过于庞大,如一次从数据库取出过多数据

集合类中有对对象的引用,使用完后未清空,产生了堆积,使得JVM不能回收

代码中存在死循环或循环产生过多重复的对象实体

使用的第三方软件中的BUG

启动参数内存值设定的过小

2、内存溢出的解决方案

第一步,修改JVM启动参数,直接增加内存(-Xms,-Xmx参数一定不要忘记加)

第二步,检查错误日志,查看“OutOfMemory”错误前是否有其 它异常或错误

第三步,对代码进行走查和分析,找出可能发生内存溢出的位置

重点排查以下几点:检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

检查代码中是否有死循环或递归调用。

检查是否有大循环重复产生新对象实体。

检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

第四步,使用内存查看工具动态查看内存使用情况

三、内存泄漏和内存溢出的区别

内存溢出是指向JVM申请内存空间时没有足够的可用内存了,就会抛出OOM即内存溢出。

内存泄漏是指,向JVM申请了一块内存空间,使用完后没有释放,由于没有释放,这块内存区域其他类加载的时候无法申请,

同时当前类又没有这块内存空间的内存地址了也无法使用,相当于丢了一块内存,这就是内存泄漏。

值得注意的是内存泄漏最终会导致内存溢出,很好理解,内存丢了很多最后当然内存不够用了。

关于Python内存泄漏和内存溢出的解决方法就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

python会内存泄漏吗_Python内存泄漏和内存溢出的解决方法相关推荐

  1. python读取excel图片尺寸_Python读取excel中的图片完美解决方法

    excel中有图片是很常见的,但是通过python读取excel中的图片没有很好的解决办法. 网上找了一种很聪明的方法,原理是这样的: 1.将待读取的excel文件后缀名改成zip,变成压缩文件. 2 ...

  2. python f检验 模型拟合度_python数据分析之线性回归,各种检验和解决方法!

    线性回归 (1)线性回归的主要内容: 有兴趣可以玩一下这个游戏:是猜相关系数的,给你一些散点图,猜相关系数,很难猜对,说明看图说明相关性不靠谱! (2)线性回归怎么做?数学公式 一个简单线性回归的例子 ...

  3. python科学计数法输出_python 不以科学计数法输出的方法

    python 不以科学计数法输出的方法 其实很简单只需两个语句: import numpy as np np.set_printoptions(suppress=True) 这样就可以搞定 以上这篇p ...

  4. Java常见的几种内存溢出及解决方法

    Java常见的几种内存溢出及解决方法[情况一]: java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另 ...

  5. MyEclipse 2015 运行tomcat 内存溢出的解决方法

    MyEclipse 2015 运行tomcat 内存溢出的解决方法 参考文章: (1)MyEclipse 2015 运行tomcat 内存溢出的解决方法 (2)https://www.cnblogs. ...

  6. ionic3生产打包javascript内存溢出的解决方法

    ionic3生产打包javascript内存溢出的解决方法 参考文章: (1)ionic3生产打包javascript内存溢出的解决方法 (2)https://www.cnblogs.com/wei- ...

  7. 内存或磁盘空间不足 Microsoft Excel无法再次打开解决方法

    内存或磁盘空间不足 Microsoft Excel无法再次打开解决方法 在网络上下载的文件,使用EXCEL打开的时候提示"内存或磁盘空间不足,Microsoft Excel 无法再次打开或保 ...

  8. python程序在命令行执行提示ModuleNotFoundError: No module named ‘XXX‘ 解决方法

    python程序在命令行执行提示ModuleNotFoundError: No module named 'XXX' 解决方法 参考文章: (1)python程序在命令行执行提示ModuleNotFo ...

  9. python open找不到文件的原因_浅谈python在提示符下使用open打开文件失败的原因及解决方法...

    题目:在提示符下使用open打开一个文件 刚开始网上看了下打开的方式,结果一直实现不了,报错是没找到这个文件,而且和我输入的文件名不一样. 错误如下: >>>open('d:\456 ...

最新文章

  1. Android开发之大位图二次採样压缩处理(源码分享)
  2. Intent中的四个重要属性——Action、Data、Category、Extras
  3. java lamda循环条件_Java lambda 循环累加求和代码
  4. 内网通 去广告_新高一攻略|让我们一起跟升学e网通名师看看如何学好高中化学...
  5. 1779: 无法言表(map+queue)
  6. subpress installed post-installation script returned error exit status 1
  7. 为什么用python的时候特别卡_【后端开发】python为什么会运行慢
  8. 设置域用户帐户的登录时间
  9. 你知道怎么用Idea抽取方法、创建class吗?
  10. Knockout开发中文API系列1
  11. 智慧工地实名制劳务管理系统
  12. 大连超级计算机,ASC19世界大学生超级计算机竞赛在我校圆满落幕
  13. 我的后台Java面经(阿里、腾讯、头条、京东、IBM等)
  14. 从零开始配置搭建云服务器(Linux系统、简明详细教程)
  15. 从共享征信黑名单到建立白名单体系:LinkEye想打造基于区块链的征信联盟
  16. Windows驱动认证
  17. web应用开发入门_Web应用程序监视入门
  18. 【信号重构】经傅里叶逆变换(IFFT)后得到实数序列-含Matlab程序
  19. 微信小程序夜间模式,实现更换皮肤,切换白天黑夜模式,简单易懂
  20. 南京理工大学计算机学院张勇,南京理工大学教师信息

热门文章

  1. 一个IT经理眼中的RTX、Simba2013与Lync
  2. 线性表--链式实现方式
  3. 实践 Ubuntu 10.10/11.04 关闭双显卡问题
  4. 电脑广告弹窗多?安利一下:程序员常用 7 款Chrome去广告插件
  5. C/C++编程笔记:数据结构二叉树的查找(前序、中序、后序、层序遍历)
  6. 什么是 C 和 C ++ 标准库?
  7. 制造业数字化经营新思路:管理平台架构及三大落地方法论
  8. 入行十年,总结出了数据仓库、数据集市、数据库的精华,你一定不能错过
  9. 有滋有味了freeeim
  10. 『转』死去度百飞鸽传书