调试异步内存泄漏

时间:2019-10-29 23:23:09

标签: python asynchronous python-asyncio aiohttp

如何调试asyncio(使用aiohttp)应用程序以查找内存泄漏?

应用程序:100个异步协程,它们从Redis读取消息,进行一些外部API http调用,并将结果保存到db中。

问题出在这里:在更大的消息数(10k-20k)上,每条消息之后,应用程序使用的RAM内存就在增加。

使用objgraph进行调试,例如:

print(objgraph.show_growth(limit=100))

每条新消息后显示的结果完全相同:

weakref                        6163        +4
dict                          19192        +3
builtin_function_or_method     1911        +3
tuple                         16880        +2
function                      25375        +1
method                          496        +1
Event                             8        +1
Condition                         8        +1
deque                            14        +1
SplitResult                      15        +1
Context                          15        +1
Thread                            7        +1

这不是我亲手创造的,所以这就是所有第三方依赖项。

还发现了有趣的物品: 词典之一(来自show_growth)是:

{'_context': <ssl.SSLContext object at 0x10a4ce228>, 
'_server_side': False, 
'_server_hostname': 
'my.host.name',
'_state': 'SHUTDOWN',
'_incoming': <_ssl.MemoryBIO object at 0x10a620b30>,
'_outgoing': <_ssl.MemoryBIO object at 0x10a620b10>,
'_sslobj': <ssl.SSLObject object at 0x10a664ac8>,
'_need_ssldata': True,
'_handshake_cb': <bound method SSLProtocol._on_handshake_complete of <asyncio.sslproto.SSLProtocol object at 0x10a664630>>,
'_shutdown_cb': <bound method SSLProtocol._finalize of <asyncio.sslproto.SSLProtocol object at 0x10a664630>>
}

如您所见,这就像是呼叫或响应的结果。是否有可能所有响应都在这里,所以它可以保存每个响应并且RAM正在增加?

如何处理? 还是可以建议另一种方法来找到弱小的应用程序?

1 个答案:

答案 0 :(得分:1)

不断发展的字典是__dict__异步内部类中的_SSLPipe

您会尝试uvloop吗?Шt是具有不同SSL传输实现的替​​代事件循环。

此外,该错误可能取决于所使用的Python版本。您是否检查了最新的Python(目前为3.8)?