Долгоживущий Python-сервис после пиков удерживает высокий RSS, хотя счётчик объектов стабилен и tracemalloc показывает, что большинство аллокаций освобождены. Почему память «не возвращается ОС» и как это чинить?
Это не утечка в логике, а фрагментация/поведение аллокаторов: pymalloc и glibc malloc держат арены/пулы, ОС не всегда может их отдать обратно. Смешение «долгоживущих» и «короткоживущих» объектов усугубляет фрагментацию.
Лечение: снижать churn и фрагментацию (reuse буферов, __slots__, пулы объектов, векторизация/NumPy вместо мелких аллокаций), разводить по жизненным циклам крупные структуры, выносить большие буферы в управляемые bytearray/мемпулы. На уровне рантайма — использовать jemalloc или аккуратно вызывать malloc_trim(0) (Linux) в моменты покоя. Архитектурно — модель процессов с ротацией воркеров (gunicorn --max-requests/--max-requests-jitter, uvicorn multiple workers), чтобы «сбрасывать» фрагментированную память. Профилировать: сравнивать RSS vs tracemalloc, смотреть malloc_info(), psutil и горячие аллокации.
Библиотека собеса по Python
Post #1352
645