У меня есть рабочий процесс, который порождает до 50 потоков и выполняет некоторые асинхронные операции (большинство из которых - HTTP-вызовы). Когда я запускаю процесс, он начинается с примерно 35 МБ используемой памяти и быстро растет до 250 МБ. С этого момента он растет еще больше, и проблема в том, что память никогда не перестает расти (хотя нарастающая фаза уменьшается со временем). Через несколько дней процесс просто перерастает доступную память и сбой.
Я провел много анализа и профилирования и не могу найти, что не так. Процессная память постоянно растет, хотя размер кучи почти постоянный. Я собрал вывод GC.stat
в электронную таблицу, которую вы можете получить здесь:
https://docs.google.com/spreadsheets/d/17TohDNXQ_MXM31CeAmR2ptHFYfvOeF3dB6WCBkBS_Bc/edit?usp=sharing
Хотя кажется, что память процесса окончательно стабилизировалась на уровне 415 МБ, она будет продолжать расти в течение следующих нескольких дней, пока не достигнет предела 512 МБ и не сработает.
Я также пробовал отслеживать объекты с помощью objectpace, но сумма памяти отслеживаемых объектов никогда не пересекается с 70-80 МБ, что идеально согласуется с отчетами GC. Где остальные 300MB + (и растущие) потрачены.. я понятия не имею.
Как бороться с этими проблемами? Есть ли какие-либо инструменты, которые могли бы дать мне более четкое представление о том, как используется память?
ОБНОВЛЕНИЕ: Драгоценные камни и ОС
Я использую следующие камни:
gem "require_all", "~> 1.3"
gem "thread", "~> 0.1"
gem "equalizer", "~> 0.0.9"
gem "digest-murmurhash", "~> 0.3", require: "digest/murmurhash"
gem "google-api-client", "~> 0.7", require: "google/api_client"
gem "aws-sdk", "~> 1.44"
Приложение развернуто на герою, хотя утечка памяти заметна при ее локальном использовании в Mac OS X 10.9.4.
ОБНОВЛЕНИЕ: Утечки
Я обновил stringbuffer и проанализировал все, что предложил @mtm, и теперь нет утечек памяти, идентифицированных с помощью инструмента leak
, без увеличения размера кучи ruby со временем, и тем не менее, память процесса все еще растет. Первоначально я думал, что в какой-то момент она перестала расти, но через несколько часов она переросла предел и процесс разбился.