NetrunНа главную

Если что-то не работает

Приложение падает с Killed или exit code 137: не хватает памяти

· 6 мин чтения

Коротко

Слово Killed в логах или код завершения 137 почти всегда означают, что приложение превысило доступную память и система принудительно его остановила. Код 137 складывается из 128 и номера сигнала 9, SIGKILL: процесс не завершился сам, его убили, поэтому сообщения об ошибке в логах обычно нет. Чаще всего память съедают модель нейросети, большой файл, целиком загруженный в pandas, браузер для Selenium или список, который растёт без конца. Сначала стоит уменьшить аппетит кода, а если приложение тяжёлое по своей природе, нужен тариф с большим объёмом памяти.

  • Код завершения 137 равен 128 плюс 9: процесс остановлен сигналом SIGKILL, чаще всего из-за превышения лимита памяти.
  • Когда приложение убивают за нехватку памяти, Python не успевает напечатать трейсбек, поэтому в логах остаётся только Killed или вообще ничего.
  • Файл CSV в pandas занимает в памяти заметно больше, чем на диске, поэтому большие файлы читают частями через параметр chunksize.
  • Ошибка JavaScript heap out of memory в Node.js — это внутренний лимит движка V8, а не лимит сервера, и лечится она иначе, чем код 137.
  • Если в docker-compose несколько сервисов, они делят между собой одну и ту же память тарифа.

Приложение запускается, немного работает и внезапно пропадает. В логах последняя строка — Killed, или проект завершился с кодом 137, или сообщений нет вовсе: только что всё печаталось, и вдруг тишина. Иногда это повторяется по кругу: приложение перезапускается, доходит до того же места и снова исчезает. Ошибки в коде при этом может и не быть — он делает ровно то, что написано, просто для этого нужно больше памяти, чем есть.

У каждого приложения на сервере есть потолок памяти. Когда процесс пытается взять больше, система не ждёт и не спрашивает: она останавливает его сигналом SIGKILL, от которого нельзя ни защититься, ни красиво завершиться. Отсюда и код 137, и отсутствие трейсбека. По-английски это называют OOM, out of memory. Ниже — как найти, что именно съедает память, и как это исправить.

Что обычно съедает память и что с этим сделать
Что ест памятьКак это выглядитЧто сделать
Модель нейросети (torch, transformers)падает сразу при запуске или на первом запросевзять модель поменьше, загружать её один раз при старте или вызывать модель через API
Большой файл в pandasпадает на чтении файлачитать частями через chunksize, брать только нужные колонки через usecols, задать dtype
Selenium или Playwright с Chromeпадает через несколько страницрежим headless, один браузер на весь скрипт, закрывать страницы и вызывать driver.quit()
Утечка в циклеработает часами, потом падает, и так по кругуограничить кэши и списки, закрывать соединения и файлы, не копить историю в памяти
Картинки и видеопадает на больших загрузкахуменьшать изображение до обработки, обрабатывать файлы по одному, сохранять на диск
Сборка фронтенда, Rust или Javaпадает на этапе сборки, а не при работесобрать фронтенд у себя и загрузить готовую папку; для Rust уменьшить параллельность сборки
Несколько сервисов в docker-composeпадает самый прожорливый сервисубрать лишние сервисы или вынести базу во внешний сервис
  1. Убедитесь, что дело в памяти#

    Посмотрите, когда именно падает приложение. Если сразу на старте — подозревайте загрузку модели, большого файла или тяжёлой библиотеки. Если через часы работы, а график памяти перед этим ровно растёт — это утечка. Код 137 бывает и по другой причине: например, когда запущен не тот файл и его останавливают принудительно, поэтому сверьте, что стартует именно ваше приложение, а не вспомогательный скрипт вроде init_db.py.

  2. Найдите, что занимает больше всего#

    Запустите приложение у себя и посмотрите, сколько памяти оно берёт, в диспетчере задач или командой вроде top. В Python помогает встроенный модуль tracemalloc: он показывает строки кода, на которых выделено больше всего памяти. Часто виновник находится за минуты — это одна строка, которая читает весь файл, создаёт модель или складывает результаты в список. Чинить имеет смысл именно её, а не всё приложение.

  3. Обрабатывайте данные частями#

    Большие файлы не нужно загружать целиком. В pandas у read_csv есть параметр chunksize — файл читается кусками, и в памяти одновременно лежит только один кусок; параметр usecols оставляет только нужные колонки. Ответы от API и выгрузки из базы тоже лучше обрабатывать постранично, а результаты сразу записывать на диск или в базу, а не копить в списке. Обычно это одна правка, которая снижает потребление в разы.

  4. Облегчите браузер и модели#

    Если в проекте Selenium или Playwright, запускайте браузер в режиме headless, без окна, держите один экземпляр на весь скрипт и обязательно закрывайте его через driver.quit(): каждый забытый браузер продолжает держать память. С нейросетями правило похожее: загружайте модель один раз при старте, а не на каждый запрос, и выбирайте облегчённую версию. Если модель всё равно не помещается, проще обращаться к ней через API провайдера, чем держать её у себя.

  5. Закройте утечки в долгоживущем коде#

    Бот или скрипт, который работает сутками, падает по кругу, если что-то в нём растёт без ограничения: словарь с историей всех пользователей, кэш без предела, список обработанных сообщений, незакрытые соединения с базой. Ограничьте размер кэша, храните историю в базе, а не в памяти, и закрывайте файлы и соединения через with. После правки понаблюдайте за памятью несколько часов: она должна выйти на ровную линию, а не расти.

  6. Если приложению правда нужно больше, возьмите тариф побольше#

    Есть приложения, которым много памяти нужно по самой своей сути: модель, которую нельзя заменить, большой датасет, несколько сервисов рядом. Тогда экономия упирается в потолок, и правильное решение — тариф с большим объёмом памяти. Сколько памяти даёт каждый тариф, указано на странице тарифов. Падение на этапе сборки, а не при работе, — отдельный случай: его обычно лечат тем, что собирают проект заранее или уменьшают параллельность сборки.

Killed и exit code 137 — не загадочный сбой, а прямое сообщение: приложению не хватило памяти. В большинстве случаев хватает одной правки — читать файл частями, закрыть браузер, загружать модель один раз. В Netrun падение из-за памяти видно сразу: на странице проекта появляется сообщение, что приложению не хватило памяти, с указанием лимита, проект перезапускается сам, а логи и нагрузка видны в кабинете. Если приложение тяжёлое по своей природе, на тарифах Pro и Max памяти больше, а у проекта с docker-compose она делится между сервисами. Попробовать Netrun.

Частые вопросы

Что значит exit code 137?

Это код, с которым завершается процесс, остановленный сигналом SIGKILL: 128 плюс номер сигнала 9. Чаще всего такой сигнал посылает система, когда приложение превысило лимит памяти. Сам процесс в этот момент ничего не успевает записать, поэтому подробностей в логах обычно нет.

Почему локально всё работает, а на сервере падает?

На компьютере у приложения гигабайты свободной памяти, а на сервере у него свой фиксированный потолок. Код, который спокойно съедает пару гигабайт на ноутбуке, на сервере упирается в лимит и останавливается. Проверьте, сколько памяти приложение берёт у вас, и сравните с лимитом тарифа.

Можно ли поймать нехватку памяти в коде и обработать её?

Почти нет. Исключение MemoryError в Python возникает редко, потому что система обычно убивает процесс раньше, чем Python успевает его выбросить. Надёжнее заранее не допускать перерасхода: читать данные частями, ограничивать кэши и следить за памятью.

Что делать с ошибкой JavaScript heap out of memory?

Это внутренний лимит движка Node.js, он может сработать раньше, чем кончится память сервера. Его поднимают флагом --max-old-space-size, но значение должно оставаться ниже лимита памяти тарифа, иначе вместо этой ошибки вы получите код 137. Если ошибка возникает при сборке фронтенда, проще собрать проект у себя и загрузить готовую папку.

Поможет ли автоматический перезапуск?

Перезапуск вернёт приложение к работе, но если причина в утечке, оно снова упадёт через то же время. Это нормально как страховка, но не как решение. Если падения повторяются по кругу, ищите, что растёт в памяти, или переходите на тариф побольше.

Что будет, если приложение упадёт?

Мы следим за проектами и перезапускаем их при сбое. Статус и логи видны в кабинете сразу, а уведомление приходит, только если приложение так и не вернулось в работу в течение часа: из-за коротких перебоев мы вас не тревожим.

Где посмотреть логи и статус проекта?

На странице проекта есть статус, логи и история событий — по ним видно, что происходит с проектом прямо сейчас. Лента логов показывает и более ранние строки: пролистайте её вверх, и они подгрузятся сами.

Чем отличается тариф Pro?

На тарифе Pro проект работает круглосуточно: сайт не засыпает и отвечает мгновенно, без паузы на пробуждение, а бот или фоновый скрипт работает постоянно, без ограничения по времени. Кроме того, на Pro больше памяти, процессора и места, а к сайту можно подключить свои домены — столько, сколько нужно, каждый с HTTPS.

Запустите свой проект

Загрузите код, ответьте на пару вопросов — и получите рабочую ссылку. Есть бесплатный тариф

Попробовать Netrun
Все статьи блога