Имеется приложение написанное не мною и до меня.
Оно отвечает за бизнес-логику телефонии, а так же за предоставление API пользования этой бизнес-логикой.
Само приложение использует библиотеки Adhearsion(для общения с Asterisk) и Sinatra для API
В определенный момент виртуальная машина подвисла на столько что даже по SSH не возможно было подключиться к ней и пришлось делать Hard Reset.
В процессе разбирательств было определено проблемное место - приложение на Ruby.
Оно в момент старта отъедало 100 метров оперативы, через пару недель оно уже отжирает более гига оперативы.
Хотелось бы понять каким образом ищутся утечки памяти, либо не закрытые/удаленые объекты в памяти
UPD:22-07-2021
на сегодняшний день ситуация такова, написал свой логер и пытаюсь в критичные для меня моменты скидывать в логи данные
по сути кидаю 2(иногда 3) параметра
1 - класс и метод откуда идет сброс в логер
2 - строка для логера
3 - необязательный атрибут - отдельный файл лога
отбросил 2 не особо важных для меня логирования отдельными файлами, это delayed job библиотека запуска задач в руби по расписанию(использую для старта звонков в астериске в нужный момент) и отдельно кидаю лог по синатре(обращения к методам и атрибуты)
теперь в основном логе собираются данные по стартам сессий, их отработке, а так же билингу
строка в логе принимает следующий вид
Время :: виртуальная память процесса|оперативная память проеесса :: данные из GC(malloc_increase_bytes-malloc_increase_bytes_limit-total_allocated_objects) :: Класс->метод вызова лога :: строка сообщения в лог
2021-07-22 09:34:19 +0200 :: 4545776|172832 :: 14869832-16777216-14064439 :: AdviserCall-> :: 17715: Start to call to adviser
2021-07-22 09:34:22 +0200 :: 4545776|172940 :: 16298832-16777216-14074552 :: Direct->run :: 17715: on end call
2021-07-22 09:34:22 +0200 :: 4545776|171628 :: 433496-16777216-14078617 :: Direct->run :: 17715: finished call: hungup (16)
2021-07-22 09:34:22 +0200 :: 4545776|171676 :: 1625480-16777216-14081883 :: Direct->run :: 17715: session.update_attributes: stop 2021-07-22 09:34:22 +0200, duration 31.0
2021-07-22 09:34:22 +0200 :: 4545776|171676 :: 2307360-16777216-14090011 :: Direct->run :: 17715: on customer.calculate_duration
2021-07-22 09:34:22 +0200 :: 4545776|171676 :: 2391720-16777216-14092322 :: AdviserCall-> :: : End callcontroller
2021-07-22 09:34:22 +0200 :: 4545776|171676 :: 2568720-16777216-14092986 :: AdviserCall-> :: 17715: after call to adviser
2021-07-22 09:34:22 +0200 :: 4545776|171684 :: 3171688-16777216-14094233 :: Direct->run :: 17715: on adv.calculate_duration
2021-07-22 09:34:22 +0200 :: 4545776|171684 :: 3224400-16777216-14095530 :: Direct->run :: 17715: unlock adviser
2021-07-22 09:34:22 +0200 :: 4545776|171704 :: 3962392-16777216-14101560 :: Direct->run :: 17715: on session.calculate_billing
2021-07-22 09:34:22 +0200 :: 4545776|171732 :: 4271248-16777216-14110094 :: Direct->run :: 17715: before EXECUTED status was: EXECUTING
2021-07-22 09:34:22 +0200 :: 4545776|171756 :: 6101592-16777216-14120962 :: Direct-> :: 7cf84f4b-7178-4c55-b6bd-3aa42019c6b6: End callcontroller
2021-07-22 09:34:22 +0200 :: 4545776|171812 :: 7845656-16777216-14122863 :: AdviserCall->run :: 17715: call.on_end: hangup-command ()
2021-07-22 09:34:22 +0200 :: 4545776|171836 :: 8181216-16777216-14124630 :: AdviserCall->run :: 17715: before calculate duration
2021-07-22 09:34:22 +0200 :: 4545776|171852 :: 8196080-16777216-14124849 :: AdviserCall->run :: 17715: before unlock adviser
2021-07-22 09:34:22 +0200 :: 4545776|171852 :: 8224112-16777216-14125307 :: AdviserCall->run :: 17715: before calculate billing
но по факту пока ничего серьезного не нарыл.
не могу найти момент где идет серьезная утечка в памяти, но на замерах получил на 10 сутках почти полтора гига в оперативе под процесс, а один раз даже обнаружил 13 гигов в виртуальной памяти
UPD(2021-08-23): обнаружил направление поиска утечки, а так же интересный баг
баг выражается в следующем - при работе с моделью в монго в определенный момент я произвожу изменение атрибута status c EXECUTING на EXECUTED, а в методе after_save этой модели сбрасываю объект в лог. и примерно в 1% случаев у меня в логе статус EXECUTED у объекта был, но при этом в базе я вижу лишь EXECUTING
что касается утечки - она образуется из-за потоков. в момент запуска приложения у меня 38 потоков, по истечению 5 суток у меня их уже под 4 сотни, пропорционально с ними растет и память. Одну из потенциальных проблем обнаружил. В сложной сессии когда клиент создает входящий вызов, я создаю ногу оператора и соединяю их, после чего оператор пином во время разговора определяет какому эксперту пойдет дозвон и произойдет подмена ноги оператора на ногу эксперта. в процессе происходит кучу еще действий в том числе и проигрывание приветствий/музычки каждому свое. В определенных ситуациях я получаю в лог сообщение об ошибке вида
[2021-08-23 18:27:37.909] ERROR Adhearsion::OutboundCall: 1741366f-01ca-48ae-8640-c53c037576d2@10.0.0.106: <Adhearsion::Call::Hangup> Adhearsion::Call::Hangup
/usr/local/rvm/gems/ruby-2.3.0/gems/celluloid-0.15.2/lib/celluloid/responses.rb:29:in `value'
/usr/local/rvm/gems/ruby-2.3.0/gems/celluloid-0.15.2/lib/celluloid/calls.rb:92:in `value'
/usr/local/rvm/gems/ruby-2.3.0/gems/celluloid-0.15.2/lib/celluloid/proxies/sync_proxy.rb:33:in `method_missing'
/usr/local/rvm/gems/ruby-2.3.0/gems/adhearsion-2.6.3/lib/adhearsion/call.rb:22:in `method_missing'
/usr/local/rvm/gems/ruby-2.3.0/gems/matrioska-0.3.0/lib/matrioska/app_runner.rb:27:in `start'
/usr/local/rvm/gems/ruby-2.3.0/gems/matrioska-0.3.0/lib/matrioska/app_runner.rb:80:in `block in match_and_run'
/usr/local/rvm/gems/ruby-2.3.0/gems/adhearsion-2.6.3/lib/adhearsion/call_controller.rb:112:in `exec_with_callback'
/usr/local/rvm/gems/ruby-2.3.0/gems/adhearsion-2.6.3/lib/adhearsion/call_controller.rb:104:in `block (2 levels) in bg_exec'
/usr/local/rvm/gems/ruby-2.3.0/gems/adhearsion-2.6.3/lib/adhearsion/foundation/exception_handler.rb:5:in `catching_standard_errors'
/usr/local/rvm/gems/ruby-2.3.0/gems/adhearsion-2.6.3/lib/adhearsion/call_controller.rb:103:in `block in bg_exec'
/usr/local/rvm/gems/ruby-2.3.0/gems/celluloid-0.15.2/lib/celluloid/thread_handle.rb:13:in `block in initialize'
/usr/local/rvm/gems/ruby-2.3.0/gems/celluloid-0.15.2/lib/celluloid/internal_pool.rb:100:in `block in create'
/usr/local/rvm/gems/ruby-2.3.0/gems/logging-1.8.2/lib/logging/diagnostic_context.rb:323:in `block in create_with_logging_context'
при этом нет упоминания самого файла приложения как источника ошибки, как следствие лишь понятие что какой-то поток в целюлоиде дал сбой и не смог выйти