首页 > 编程 > Python > 正文

记一次python 内存泄漏问题及解决过程

2020-02-15 23:49:21
字体:
来源:转载
供稿:网友

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

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

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

一、复现问题

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

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

服务端代码:

from aiohttp import webasync def hello(request): return web.json_response(await request.json())app = web.Application()app.add_routes([web.post('/', hello)])web.run_app(app)

客户端代码:

import asyncioimport aiohttpasync def foo(times): data = {'foo': 1} async with aiohttp.ClientSession() as session:  for x in range(times):   resp = await session.post('http://localhost:8080', json=data)   if not x % 100:    print(await resp.json())loop = asyncio.get_event_loop()loop.run_until_complete(foo(100000))loop.close()

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

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

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

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

二、解决内存泄漏的过程

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表