精华内容
下载资源
问答
  • 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题。 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”。 1、内存泄露的...
  • I have a Python program that runs a series of experiments, with no data intended to be stored from one test to another. My code contains a memory leak which I am completely unable to find (I've look a...

    1586010002-jmsa.png

    I have a Python program that runs a series of experiments, with no data intended to be stored from one test to another. My code contains a memory leak which I am completely unable to find (I've look at the other threads on memory leaks). Due to time constraints, I have had to give up on finding the leak, but if I were able to isolate each experiment, the program would probably run long enough to produce the results I need.

    Would running each test in a separate thread help?

    Are there any other methods of isolating the effects of a leak?

    Detail on the specific situation

    My code has two parts: an experiment runner and the actual experiment code.

    Although no globals are shared between the code for running all the experiments and the code used by each experiment, some classes/functions are necessarily shared.

    The experiment runner isn't just a simple for loop that can be easily put into a shell script. It first decides on the tests which need to be run given the configuration parameters, then runs the tests then outputs the data in a particular way.

    I tried manually calling the garbage collector in case the issue was simply that garbage collection wasn't being run, but this did not work

    Update

    Gnibbler's answer has actually allowed me to find out that my ClosenessCalculation objects which store all of the data used during each calculation are not being killed off. I then used that to manually delete some links which seems to have fixed the memory issues.

    解决方案

    You can use something like this to help track down memory leaks

    >>> from collections import defaultdict

    >>> from gc import get_objects

    >>> before = defaultdict(int)

    >>> after = defaultdict(int)

    >>> for i in get_objects():

    ... before[type(i)] += 1

    ...

    now suppose the tests leaks some memory

    >>> leaked_things = [[x] for x in range(10)]

    >>> for i in get_objects():

    ... after[type(i)] += 1

    ...

    >>> print [(k, after[k] - before[k]) for k in after if after[k] - before[k]]

    [(, 11)]

    11 because we have leaked one list containing 10 more lists

    展开全文
  • 一次python 内存泄漏解决过程

    千次阅读 2019-04-16 20:04:45
    最近工作中慢慢开始用python协程相关的东西,所以用到了一些相关模块,如aiohttp, aiomysql, aioredis等,用的过程中也碰到的很多问题,这里整理了一次内存泄漏的问题 通常我们写python程序的时候也很少关注内存这...

    最近工作中慢慢开始用python协程相关的东西,所以用到了一些相关模块,如aiohttp, aiomysql, aioredis等,用的过程中也碰到的很多问题,这里整理了一次内存泄漏的问题

    通常我们写python程序的时候也很少关注内存这个问题(当然可能我的能力还有待提升),可能写c和c++的朋友会更多的考虑这个问题,但是一旦我们的python程序出现了

    内存泄漏的问题,也将是一件非常麻烦的事情了,而最近的一次代码中也碰到了这个问题,不过好在最后内存溢出不是我代码的问题,而是所用到的一个包出现了内存的问题,下面我通过一个简单的代码模拟出内存的问题,然后也会将解决的过程描述一下,希望能帮助到遇到同样问题的朋友。

    一、复现问题

    其实这次主要是在使用aiohttp写一个接口的时候出现的问题,其实复现出问题非常容易,我们实现一个简单的接受post请求接口的服务端,然后实现一个并发的客户端来访问这个接口,来查看内存的情况

    注意: 这个问题是在一个包的特定版本出现的:multidict==4.5.1,我在整理这个文章2个小时前作者已经修复了这个问题发布了4.5.2版本,已经修复了内存的问题,并且我也进行了测试验证

    服务端代码:

     

    客户端代码:

     

    因为我的代码是在linux上跑的,或者mac上我们都可以通过htop非常方面的实时查看我们程序内存的占用情况,我们先将服务端启动,查看一下我们此时的内存情况可以看到占用的

    非常少,当我们打开客户端之后,再次观察我们可以看到内存不断增长,及时我们客户端运行完毕内存也不会降低。

     当客户端结束之后的内存:

    如果客户端不停止的话内存会一直涨,最后的结果就是把你的系统内存吃完,然后被系统杀掉你的进程。

     

    二、解决内存泄漏的过程

    像上面的例子是一个非常简单的程序,不复杂我们也并没有做上面复杂的操作就是一个简单的接受post请求的服务端,但是如果是在实际的项目中我们可能会写非常复杂的业务逻辑,那到时候我们又如何找到是哪里导致的内存问题,当我碰到这个问题的时候,其实我和很多接触python不久的人差不多,也是不知道怎么查这种问题,各种百度各种查,也找到了好多推荐的工具,memory_profiler库,objgraph库,graphviz工具,但是都没有帮助我迅速的找到问题点在哪里,最后看到标准库中的tracemalloc,地址:https://docs.python.org/3/library/tracemalloc.html

    通过这个包很快帮我找到了内存泄漏的地方

    接下来按照官网的方法我将代码进行改写,来测试到底哪里的问题导致的内存泄漏,更改后的服务端代码为:

     

    注意print(top_stats)这行打印的结果最后要关注

     其实这里就是新增加了一个路由get_info, 我们启动服务端之后开启客户端,当我们客户端运行完毕之后,可以看到内存已经涨上去了,并且没有不会释放,这个时候,可以直接通过浏览器访问get_info这个路由看看print打印的内容,这里将会打印出你程序运行到这个时候那一行的代码内存增长的比较多,进行一次排序,前面的几个其实都是需要你关注的,因为这里数据较多,我就只打印如下前几个数据

     

    我们拿第一行来说,我们可以非常清楚的指导web_response的56行代码导致内存增长的最多,当然如果是我们复杂的项目也可以通过类似的方法,这样就可以非常快捷的找到我们代码中哪些地方会造成内存溢出,便于排查问题,我们点进去看看这行代码:

    我们找到最终行,这个时候我们大致就可以看出哪里的问题了,我们接着看 CIMultiDict

     

    我们可以看到这个它继承 MultiDict 其实这里我们已经应该知道问题就是处在这个MultiDict上了

    而这个最终其实最终就是MultiDict这个包,问题出在了这个包上,这个项目是在这里维护的:https://github.com/aio-libs/multidict

    查看这个包的时候看到了,果然有人和我遇到了同样的问题,问题就是出在这里了,已经有人提交了bug

    https://github.com/aio-libs/multidict/issues/307

    不过不得不说国外的程序员真的是热爱自己的职业,很快这个问题得到了aio-libs小组中人的回应,问题也在我整理这个博客的时候被修复了,在最新的版本:4.5.2中已经测试没有内存泄漏的问题

     

    三、总结

    在这里处理的过程中,其实发现了自己很多的不足,查找问题的方式,以及遇到这种问题的解决思路,不过经过这次,至少下次遇到同样的问题,自己能很快的去查找

    以及解决问题,还有就是针对https://docs.python.org/3/library/tracemalloc.html这个库的使用,也推荐大家多了解一下。

    展开全文
  • 定位python内存泄漏问题

    万次阅读 2019-07-10 22:57:02
    记一次 Python 内存泄漏的排查 背景 上周使用我的python web框架开发的第二个项目上线了,但是没运行几天机器内存就报警了,8G内存使用了7G,怀疑有内存泄漏,这个项目提供的功能就是一堆机器学习模型,对历史数据...

    记一次 Python 内存泄漏的排查

    背景

    上周使用我的python web框架开发的第二个项目上线了,但是没运行几天机器内存就报警了,8G内存使用了7G,怀疑有内存泄漏,这个项目提供的功能就是一堆机器学习模型,对历史数据进行训练,挑选出最优的5个模型,用作未来数据的预测,所以整个项目有着数据量大,运行时间长的特点,就是把策略的离线工作搬到了线上。

    定位内存泄漏

    第一步:确定是否有内存泄漏

    pympler检查是否有内存泄漏,程序入口处初始化该工具

    from pympler import tracker,summary,muppy
    memory_tracker = tracker.SummaryTracker()
    

    接口返回处打印内存差异,观察内存是否有泄漏

    memory_tracker.print_diff() # 本次内存和上次内存块的差异
    

    我们用的sanic,所以直接在main.py文件添加如下代码:

     from pympler import tracker,summary,muppy
     memory_tracker = tracker.SummaryTracker()
    
     @app.middleware('request')
     async def set_request_id(request):
         log_id = request.headers.get('log-id')
         threading.currentThread().logid = log_id
         gc.collect()
         memory_tracker.print_diff()
    

    然后我们访问接口,多触发几次,不用看前两次,等输出稳定后,如果有内存泄漏是如下输出:

    在这里插入图片描述
    上图显示每次都有4类泄漏对象,一共泄漏约60K的内存

    如果没有内存泄漏,没有数据输出

    在这里插入图片描述

    第二步:确定内心泄漏的代码块

    我们确定程序有内存泄漏后,就想办法定位到代码块,就是我们自己写的代码,通过一步一步debug,注释,returncontinue等方式定位到造成泄漏的代码块,下面的代码块就是遍历所有模型,然后挨个执行训练方法,因为有20多个模型,我不能挨个注释每次对象来定位,卡在这里了。
    在这里插入图片描述

    第三步:确定泄漏点

    tracemalloc定位泄漏点,python3.7.3自带,在main.py中添加如下代码:

    tracemalloc.start(25)
    snapshot = tracemalloc.take_snapshot()
    @app.middleware('response')
    async def print_on_response(request, response):
        global snapshot
        gc.collect()
        snapshot1 = tracemalloc.take_snapshot()
        top_stats = snapshot1.compare_to(snapshot, 'lineno')
        print("[ Top 10 differences ]")
     	for stat in top_stats[:10]:
        	 if stat.size_diff < 0:
    			continue
     		 print(stat)
     	snapshot = tracemalloc.take_snapshot()
    

    继续访问接口,多访问几次,输出如下,直接定位到具体泄漏的代码位置
    在这里插入图片描述

    图中所有的泄漏点都定位到pandas库,但是我用这些文件搜索内存泄漏,都没有搜到相关内存泄漏的问题,所以得寻找谁调用这些地方,以/home/doctorq/.local/share/virtualenvs/scscore-K9x97I77/lib/python3.7/site-packages/pandas/core/window.py:859为例,我们要找到我们写的代码哪里调用触发泄漏点

    第四步:打印调用链

    看了tracemalloc文档也没找到打印调用链的方法,后来灵机一动直接在这个文件加了下面代码:

    raise Exception("doctorq")
    

    然后在接口里catch异常,添加logging.exception(e),然后触发接口,打印堆栈信息:

    ERROR:root:doctorq
    Traceback (most recent call last):
      File "/home/doctorq/python-dev/scscore/src/forecasting/forecast.py", line 83, in update_method
        n_fraction=n_fraction)
      File "/home/doctorq/python-dev/scscore/src/forecasting/trainer.py", line 113, in training
        n_fraction=n_fraction)
      File "/home/doctorq/python-dev/scscore/src/forecasting/trainer.py", line 205, in train_machine_learning_model
        is_train=True).dropna()
      File "/home/doctorq/python-dev/scscore/src/feature_engineering/features.py", line 34, in get_feature
        history_same_periods=history_same_periods, zero_replace=zero_replace)
      File "/home/doctorq/python-dev/scscore/src/feature_engineering/sale_relate_feature.py", line 65, in get_feature
        store_and_sku=store_and_sku)
      File "/home/doctorq/python-dev/scscore/src/feature_engineering/sale_relate_feature.py", line 85, in get_rolling_feature
        rolling_result = self.get_rolling_result(window, rolling_obj, rolling_types)
      File "/home/doctorq/python-dev/scscore/src/feature_engineering/sale_relate_feature.py", line 169, in get_rolling_result
        rolling_result = self.rolling__(rolling_obj, rolling_type)
      File "/home/doctorq/python-dev/scscore/src/feature_engineering/sale_relate_feature.py", line 190, in rolling__
        return rolling_obj.min()
      File "/home/doctorq/.local/share/virtualenvs/scscore-K9x97I77/lib/python3.7/site-packages/pandas/core/window.py", line 1723, in min
        return super(Rolling, self).min(*args, **kwargs)
      File "/home/doctorq/.local/share/virtualenvs/scscore-K9x97I77/lib/python3.7/site-packages/pandas/core/window.py", line 1069, in min
        return self._apply('roll_min', 'min', **kwargs)
      File "/home/doctorq/.local/share/virtualenvs/scscore-K9x97I77/lib/python3.7/site-packages/pandas/core/window.py", line 879, in _apply
        result = np.apply_along_axis(calc, self.axis, values)
      File "/home/doctorq/.local/share/virtualenvs/scscore-K9x97I77/lib/python3.7/site-packages/numpy/lib/shape_base.py", line 380, in apply_along_axis
        res = asanyarray(func1d(inarr_view[ind0], *args, **kwargs))
      File "/home/doctorq/.local/share/virtualenvs/scscore-K9x97I77/lib/python3.7/site-packages/pandas/core/window.py", line 875, in calc
        closed=self.closed)
      File "/home/doctorq/.local/share/virtualenvs/scscore-K9x97I77/lib/python3.7/site-packages/pandas/core/window.py", line 858, in func
        raise Exception("doctorq")
    Exception: doctorq
    

    定位到我们代码触发点如下:

    在这里插入图片描述
    调用的就是pandasRolling的一系列方法,然后搜索该方法是否有泄漏问题

    在这里插入图片描述

    第一个链接链接就是说这些方法(rolling.min/max)有泄漏,pandas rolling max leak memory,具体因为啥泄漏的,也没时间细究,反正issue里说回退到0.23.4是没问题的,那么就回退试试:

    pipenv install pandas==0.23.4
    

    然后我们再用pympler定位有没有内存泄漏,pandas内存泄漏的问题是修复,剩下来就省memoryview的小泄漏了,明天继续

    在这里插入图片描述

    总结

    定位的过程略耗时,不过经过这么一折腾,也算是有经验了,各种工具一阵堆,泄漏问题确定-定位代码块-定位泄漏点-搜索已知泄漏点-解决掉。

    展开全文
  • 1.明确内存泄漏的几种场景。 1.没有开gc,或者gc设为debug状态,导致交叉引用没有被回收调 2.如果一个数据在逻辑上不应该存在,但是因为代码上没有做相关清除操作,导致他还存在,也是一种泄漏 举个栗子,例如...

    1.明确内存泄漏的几种场景。

          1.没有开gc,或者gc设为debug状态,导致交叉引用没有被回收调

          2.如果一个数据在逻辑上不应该存在,但是因为代码上没有做相关清除操作,导致他还存在,也是一种泄漏

              举个栗子,例如我要记录最近50天的某个基金的日化收益率,定义一个全局的字典global_dict,运行了一个脚本进行计算,没10分钟算一次,但是我没有进行clear操作,每次的计算只是单纯的赋值dict[date] = rate,按理来说dict["五十天前"]的收益率都是不需要的,就是一种泄漏。

          3.这种情况出现在python3.4之前,因为3.4已经修复了,是这样的,如果一个类定义了__del__,并且该类存在循环引用的情况,这时候gc就会把这个类放在gc.garbage当中,不会去做回收,可以说是跳出了分代回收的机制,但是3.4之后的版本就没有这种情况,会把他回收调。

     

    2.根据场景去找问题

         1.如果是第一种情况解决就最简单了,可以用某个调试库连接到线上的进程,这里推荐pyrasite,但是要注意,这东西很久都没有更新了,所以有可能会和py的版本出现不相容的情况,例如python3.6就把itervalues改为values,导致一些工具用不到,不过没关系,我们只是用它来连上去,看gc而且,等我们连上进程后,就可以调用gc.isenable()去看gc有没有打开了或者状态是否正确

         2.第二种情况就比较复杂了,我建议线下压测复现,不管是rpc还是一般的web服务,我相信写压测脚本都不难。

            这里我推荐一个库,objgraph,这个库是基于gc的,他带有以下几个功能。

            1.show_growth(limit = n),这个函数的作用就是距离上一次这个函数调用之后,那几个类型增长得最多,显示前n个。

            2.show_backrefs()/show_backrefs(),这个函数的作用就是找出某个object的引用链。

            好了我们知道这个库有2个这样的功能的函数就好搞了,第一步我们可以在每一个接口的出口加一个show_growth(),然后根据我们自己的逻辑,去看那些类型增长异常,首先这些类型一般是我们自定义的类型,不太可能是基础类型。找到异常类型之后,我们就可以调用函数去找出这个类型的引用链,重而确定bug。

           3.第三种情况,有可能在第二种情况下找出来,我们的解决方法可以是把python版本进行一个升级,或者做相关的修改。

    展开全文
  • Python pylucene Theano 多线程问题
  • python 内存泄漏与内存溢出

    千次阅读 2018-12-07 09:17:07
    ***内存泄漏:***你使用malloc或new向 内存申请了一块内存空间,但没有用free以及delete对该块内存进行释放,造成程序失去了对该块内存的控制. 内存溢出:你申请了10个字节的内存,但写入了大于10个字节的数据 内存泄漏 ...
  • 一个python后台服务,刚灰度上线,内存就疯狂上涨。回退之后内存并没有下降。 内存增长主要几种情况: 1. 对象被全局变量引用,生命周期长; 2. 申请的对象引用周期长; 3. 垃圾回收机制被禁用 推荐的定位...
  • python内存泄漏Fugue uses Python extensively throughout the Conductor and in our support tools, due to its ease-of-use, extensive package library, and powerful language tools. One thing we’ve learned ...
  • 然而最近使用python2.7 urllib2和request的时候却无意中发现可能存在严重的内存泄漏问题,或者说垃圾回收有问题。stackoverflow了一下,确实有很多人反应了相关的问题,至今还没解决。综合了各种解决方案,最终确定...
  • 关于Python的urllib2模块内存泄漏的问题以及解决方案问题描述失败尝试改用Requests模块在read()中加入数字参数使用with/contextlib.closing强制去除变量循环引用 问题描述 (环境:Red Hat 7.3 / Python 2.7.5 ) ...
  • 张炎泼先生于2016年加入白山云科技,主要负责对象存储研发、数据跨机房分布和修复问题解决等工作。以实现100PB级数据存储为目标,其带领团队完成全网分布存储系统的设计、实现与部署工作,将数据“冷”“热”分...
  • python-python内存泄露跟踪

    千次阅读 2019-04-16 11:23:55
    内存泄漏的经典定义是曾经使用过一次的内存,现在却没有,但还没有被回收。使用纯Python代码几乎不可能。但正如Antoine指出的那样,即使您不需要保留所有数据,您也可以通过允许数据结构无限制地增长来轻松地消耗...
  • 在linux上面通过selenium的webdriver抓取数据的时候需要正确的关闭浏览器,不然就会出现内存泄漏的问题,注意下面的close和quir都需要加上去,其中close是关闭chromium,而quit则是关闭chromedriver的例如:simulated_...
  • 打开控制面板搜索系统,点击查看高级系统设置 点击设置 高级->更改 如图所示 **修改内存大小可以按照需要来定,够用就行,不要设置得过大
  • 延迟绑定出现在闭包问题中。下面我们看一个闭包的例子: def (n): def mul(x): ... 可能会导致内存泄漏 当然缺点可以通过人为避免。 现在我们来看看另一个会引出延迟绑定的例子: def multiplier
  • 笔者曾经开发过的几个大型...Python 中的内存泄漏通常发生在无限增长的模块级变量中。这可能是一个具有无穷大 maxsize 的 lru_cache 变量,也可能是一个在错误范围内声明的简单列表。 泄漏也不是只有发生在你自己写...
  • 对应的解决方案是: 响应特征 1:构造一个字典类型,其: 我们使用的解释器版本为 CPython 2.7.13,所以是 __builtin__ 而不是 3.x 的 builtins 该方案存在一些问题,但在我们这个场景中恰好够用了,后面复盘时再...
  • 上周五晚上主营出现部分设备掉线,经过查看日志发现是由于缓存系统出现长时间gc导致的...然后紧急把剩余未gc的一个节点内存dump下来,使用mat工具打开发现,com.mysql.jdbc.NonRegisteringDriver 对象占了堆内存的大...
  • 问题描述 ...解决方案 起初使用大家建议的plt.close()回收内存,但是无效。 后来查阅源码,plt.figure的参数中含义一个clear,默认为False,该参数为True时,且存在一个figure实例时,会自动clear掉旧fi
  • node.js内存泄露Once we begin to type that code, we already introduce bugs and allocating memory without knowing it. How we manage them can make or mar our software.ØNCE我们开始键入的代码,我们已经...
  • 同样的深度学习模型在linux运行没有遇到内存泄漏的问题,迁移到Windows就出现了问题。 报错信息为:numpy.core._exceptions.memoryerror unable to allocate 查了一下GPU Memory使用量没有爆(爆也不是提示这个信息...
  • 内存溢出的解决方案  第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)  第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。  第三步,对代码进行走查和分析,找...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,578
精华内容 4,231
关键字:

python内存泄漏解决方案

python 订阅