Отладка утечек памяти asyncio - PullRequest
1 голос
/ 30 октября 2019

Как отладить приложение asyncio (с помощью aiohttp) для обнаружения утечек памяти?

Приложение: 100 сопрограмм asyncio, которые читают сообщения из Redis, выполняют некоторые внешние вызовы HTTP API и сохраняют результаты в db.

Проблема здесь: при большем количестве сообщений (10k-20k) объем оперативной памяти, используемой приложением, увеличивается сразу после каждого сообщения.

Выполнение отладки с помощью 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>>
}

Как видите, это что-то вроде результата вызова или ответа. Возможно ли, что все ответы здесь, так что они сохраняют каждый ответ, а объем оперативной памяти увеличивается?

Как с этим бороться? Или вы можете посоветовать другой подход, чтобы найти слабое место приложения?

1 Ответ

1 голос
/ 30 октября 2019

Растущий словарь - __dict__ из _SSLPipe внутреннего класса asyncio.

Если вы попробуете uvloop , это альтернативный цикл обработки событий, имеющий другую реализацию транспорта SSL.

Также ошибка может зависеть от используемой версии Python. Вы проверяли последний Python (3.8 на данный момент)?

...