SIGKILL при выделении памяти в C++
Я разрабатываю приложение для встроенной системы с ограниченной памятью (Tegra 2) на C++. Я обрабатываю NULL результаты new
а также new[]
во всем коде, который иногда происходит, но приложение может справиться с этим.
Проблема в том, что система убивает процесс с помощью SIGKILL, если память полностью исчерпана. Могу ли я как-то сказать, что new
должен просто вернуть NULL вместо того, чтобы убить процесс?
2 ответа
Я не уверен, какую ОС вы используете, но вам следует проверить, поддерживает ли она оппортунистическое распределение памяти, как в Linux.
Если он включен, может произойти следующее:
- Ваш
new
или жеmalloc
получает действительный адрес из ядра. Даже если не хватает памяти, потому что... - Ядро на самом деле не выделяет память до самого момента первого доступа.
- Если используется вся "перегруженная" память, у операционной системы нет никаких шансов, кроме как уничтожить один из задействованных процессов. (Слишком поздно сообщать программе о нехватке памяти.) В Linux это называется Out Of Memory Kill (OOM Kill). Такие убийства регистрируются в буфере сообщений ядра.
Решение: отключить перезапуск памяти:
echo 2 > /proc/sys/vm/overcommit_memory
На ум приходят две идеи.
1.) Напишите свою собственную функцию выделения памяти, а не в зависимости от new
непосредственно. Вы упомянули, что находитесь во встроенной системе, где специальные распределители довольно распространены в приложениях. Вы запускаете свое приложение непосредственно на оборудовании или в процессе на уровне исполнительной власти / ОС? Если последнее, есть ли системный API для выделения памяти?
2.) Проверьте C++ set_new_handler
и посмотрим, может ли это вам помочь. Вы можете запросить, чтобы специальная функция вызывалась, когда new
распределение не удается. Возможно, в этой функции вы можете предпринять действия, чтобы предотвратить выполнение процесса, который убивает процесс. Ссылка: http://www.cplusplus.com/reference/std/new/set_new_handler/