Стендап Сьогодні
📢 Канал в Telegram @stendap_sogodni
🦣 @stendap_sogodni@shevtsov.me в Федиверсі

🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!

29.08.2025

Раптові витрати памʼяті та куди дивитися

#RubyOnRails

Довелося цього тижня зʼясовувати, чому застосунок на Rails несподівано почав споживати на кілька гігабайтів памʼяті більше. Поверхнево причина була зрозуміла — бо в цей застосунок зайшла частина іншого застосунку, відбувається таке собі злиття. Та тут й крилася проблема: в проблемний реліз потрапила ціла пачка наче безпечних змін — загальним обсягом десь у 20 тисяч рядків. Ну й що з нею робити?

Перша теорія — що це сам код витрачає стільки памʼяті — мені відразу здалася неправдоподібною. Код взагалі не дуже споживає памʼять, навіть в інтерпретованій мові. Продукти виконання коду, тобто стан — можуть. Але тоді стає питання — де той стан зберігається, бо зазвичай у вебзастосунку весь стан відкидається по закінченню запиту.

Почав перевіряти нові константи та класові змінні — ну, знайшов кілька сотень регулярних виразів. Зробив швиденько скрипт, щоб просто завантажити ці вирази та подивитися витрати памʼяті — а вони мінімальні. Ну і якщо чесно, то прямо гігабайти стану це треба ще вигадати, ніхто такого в Ruby не робить. Втім, треба ж шукати причину…

А варто було з усіх змін відразу подивитися на зміни в залежностях. А тут — в проєкт підтягнувся славетний гем mini_racer - обгортка рушія V8 для Ruby. Відчуваєте вагу? V8 це вам не купка регулярок!

Отже, виявилося, що з деяких причин версія mini_racer була старуватою, та мала проблеми із Ruby 3.4, або може з свіжим сервером Puma - в будь-якому разі, щось заважало цьому гему звільняти старі контексти V8, та вони й засмічували памʼять. Оновленням гему все розвʼязалося.

У таких випадках раптових змін завжди є конкретна причина, залишається її знайти.