Стендап Сьогодні
📢
Канал в Telegram @stendap_sogodni
🦣
@stendap_sogodni@shevtsov.me в Федиверсі
29.08.2025
Раптові витрати памʼяті та куди дивитися
Довелося цього тижня зʼясовувати, чому застосунок на Rails несподівано почав споживати на кілька гігабайтів памʼяті більше. Поверхнево причина була зрозуміла — бо в цей застосунок зайшла частина іншого застосунку, відбувається таке собі злиття. Та тут й крилася проблема: в проблемний реліз потрапила ціла пачка наче безпечних змін — загальним обсягом десь у 20 тисяч рядків. Ну й що з нею робити?
Перша теорія — що це сам код витрачає стільки памʼяті — мені відразу здалася неправдоподібною. Код взагалі не дуже споживає памʼять, навіть в інтерпретованій мові. Продукти виконання коду, тобто стан — можуть. Але тоді стає питання — де той стан зберігається, бо зазвичай у вебзастосунку весь стан відкидається по закінченню запиту.
Почав перевіряти нові константи та класові змінні — ну, знайшов кілька сотень регулярних виразів. Зробив швиденько скрипт, щоб просто завантажити ці вирази та подивитися витрати памʼяті — а вони мінімальні. Ну і якщо чесно, то прямо гігабайти стану це треба ще вигадати, ніхто такого в Ruby не робить. Втім, треба ж шукати причину…
А варто було з усіх змін відразу подивитися на зміни в залежностях. А тут — в проєкт підтягнувся славетний гем mini_racer - обгортка рушія V8 для Ruby. Відчуваєте вагу? V8 це вам не купка регулярок!
Отже, виявилося, що з деяких причин версія mini_racer
була старуватою, та мала проблеми із Ruby 3.4, або може з свіжим сервером Puma - в будь-якому разі, щось заважало цьому гему звільняти старі контексти V8, та вони й засмічували памʼять. Оновленням гему все розвʼязалося.
У таких випадках раптових змін завжди є конкретна причина, залишається її знайти.