Как бороться с утечкой памяти в Linux?

914
swordfeng

Я знаю, что вилочную бомбу можно предотвратить, ограничив число процессов одного пользователя, и утечка памяти не замерзнет, ​​моя ОС для Linux имеет OOM killer. Но как насчет бомбы с утечкой памяти?

#include <vector> #include <unistd.h> #include <ctime> #include <cstdlib>  using namespace std;  int main() { srand(time(NULL)); vector<int> vec; do { try { for (int i=0; i<10000000; i++) vec.push_back(rand()); } catch (bad_alloc e) { } fork(); } while (1); return 0; } 

Мой Linux завис после того, как попробовал этот код. Могу ли я в любом случае предотвратить его замерзание?
Код протестирован на Archlinux, Linux 4.0.5

скомпилируйте код, используя эту команду: g++ -o test test.cpp

Дополнительная информация: поскольку код может поглотить всю мою память, просто разветвившись несколько раз, он не похож на обычную вилочную бомбу, а ограничение числа процессов бесполезно. Кроме того, fork () часто выполняется (когда памяти мало), поэтому OOM-killer намного медленнее, чем вилки. В результате я должен использовать Alt-SysRq-REI, чтобы остановить эти процессы, но это не то, что я хочу.

Я впервые спрашиваю о SuperUser. Помоги мне, если мой вопрос неуместен. И спасибо за вашу помощь.

3
Я не совсем понимаю вопрос. Вы пытаетесь предотвратить быстрое истощение памяти? Почему это происходит с обычной программой? (Если только это не корпоративная среда, и вы не хотите чрезмерно укрепить свои рабочие станции.) oldmud0 8 лет назад 0
@ oldmud0 Я считаю, что это не должно происходить с обычными программами. Тем не менее, Firefox несколько раз останавливал мою систему, возможно, из-за утечки памяти (я думаю). Но обычная программа с утечкой памяти всегда останавливается OOM-killer. Поэтому я только начал искать причину. swordfeng 8 лет назад 0

1 ответ на вопрос

1
Dan Cornilescu

It doesn't have to be a memory leaking fork bomb - even, for example, a make -j (or with a too high j factor) on a moderate code size or any process spawning a pile of descendents (fewer than the reasonable limit for an active user), each chewing an amount of memory significant by itself but too small to be targeted by the OOM killer (or to offer a significant relief when nailed by the OOM killer) can have have a similar effect.

It's possible to write a customized monitoring script/tool (to be executed by root at high priority) which could watch for such process spawning patterns and, if necessary, kill them by pgid or userid (i.e simultaneouly, not one by one like the OOM killer) before they become fatal to the system. Would work for reasonable spawning/resource draining rates, but I'm not sure if possible for just any rates.

Так что ядро ​​не может этому помешать, верно? Спасибо за ваш ответ. swordfeng 8 лет назад 0
Не с помощью метода, который я знаю. Dan Cornilescu 8 лет назад 0
На самом деле, cgroups ядра не могут ограничить ресурсы, такие как память, которые будут соблюдаться здесь? Контролировать, а затем пытаться поймать это своего рода условие гонки, но я думаю, что предопределенные ограничения гораздо легче осуществить. ttbek 6 лет назад 0
@ttbek с предопределенными ограничениями трудно найти достойный баланс между недоиспользованием системы, когда мало пользователей / процессов активно, и перегрузкой системы, когда активно много таких пользователей / процессов. В 32-ядерной системе я хотел бы получить эквивалент `-j32`, если один пользователь собирает, и` -j8`, если 4 пользователя строят. Любое значение в одном случае в порядке, но в другом - нет. Dan Cornilescu 6 лет назад 0
@DanCornilescu Вы можете сделать это. Доля ЦП (не квота) может быть назначена пользователям как 250 каждый. Неиспользуемые общие ресурсы доступны для всех, поэтому одно пользовательское здание может использовать все доступные циклы ЦП, но при работе 4 они получают по 1/4 каждого из циклов. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/sect-cpu-Example_Usage.html По предопределенному, что я имел в виду примерно так, как указано выше, ядро ​​способно извлечь циклы ЦП из пользователь один, даже если его процесс начался первым. ttbek 6 лет назад 0
В некоторых других областях обычно используется более жесткое ограничение, например, это обычно при формировании HD, когда 5% резервируется для root / system. Резервирование нескольких сотен МБ ОЗУ для root с помощью контроллера памяти cgroups (или cgroups2) может (или не может, я не уверен в этом) помочь против предлагаемого сценария. Он должен запускать OOM всякий раз, когда граница пересекается, хотя вы можете также использовать его для запуска пользовательских функций, если я не забуду. Может быть, все еще гонка, но я думаю, что если ядро ​​не сможет выиграть гонку, вам не повезет с чем-либо еще. ttbek 6 лет назад 0