У меня есть следующая проблема: программа имеет ошибку как следующее
int main() {
for(;;) {
char *p = (char*)std::malloc(1024);
std::memset(p, 1, 1024);
}
}
И это продолжает выделять память полностью, пока моя система не начинает страницы свопинга других приложений в пользу той программы, и я ничего не могу больше делать на поле. Я несколько раз поражал эту проблему с различными приложениями (сегодня, это были с лунным светом 2 беты в Firefox). Я, хотя проблема состоит в том, потому что программа заставляет память другой программы быть выгруженной, и таким образом, она могла использовать больше физической памяти.
Естественно я изучил ulimit и нашел две настройки
-m
максимальный размер резидентного набора
-v
размер виртуальной памяти
Я считал, что первое обозначает общий размер физической памяти, который процесс может использовать сразу. Мне кажется, что это более разумно, чем общий размер виртуальной памяти, потому что это может быть совместно использовано, и это могло быть незначительно вообще, потому что это выгружается так или иначе. Таким образом, я добавил следующее к моему .bashrc
после рассмотрения обычных размеров резидентного набора с top
, которые располагаются приблизительно до 120 МБ для обычной сессии Firefox, я нашел.
# limit usage to 256MB physical memory out of 1GB
ulimit -m 262144
Но после выполнения моего выше тестового отрывка, это все еще brough моя система вниз, и я должен был ожидать приблизительно 5 минут до терминала, распознанного мой ^C
нажатия клавиш. Обычно, если я не реагирую в течение первых нескольких секунд, в этих ситуациях я могу только нажать кнопку сброса, которую я действительно не люблю - таким образом, у кого-либо есть стратегия того, как решить это? Почему физическое ограничение не работает? Мне кажется, что этот путь другие приложения должен все еще иметь достаточно физической памяти для реакции разумно.
Вы пробовали -v
флаг?
Резидентный рабочий набор определяется максимальным объемом памяти, сохраненным как рабочий набор в RAM перед свопингом. Таким образом это не ограничит общий объем памяти, включительно подкачал части рабочего набора. -v
флаг должен сделать задание.
РАЗМЕР ВИРТУАЛЬНОЙ ПАМЯТИ: самое полезное из связанных с памятью ограничений, потому что это включает все типы памяти, включая стек, "кучу" и файлы с отображенной памятью. Попытки выделить память сверх этого предела перестанут работать с ошибкой из памяти.
Довольно удивительно, что ресурсы в сети, описывающей это подробно, не действительно легко найти! Я сделал эксперимент на своем поле Linux.
Это останавливается за исключением с
ulimit -v 100000
и не сделал с -m
флаг. Единственной вещью, которая удивила меня, является исключение:
segmentation fault
Я ожидал бы out of memory
.
Классическая утечка памяти. Я боюсь, Вам нужно к bugfix рассматриваемое приложение, нет очень операционной системы, может сделать. Вся операционная система могла сделать, ограничивают память для одного приложения, но затем рассматриваемое приложение было бы crash/segfault, и, возможно, возьмите операционную систему или по крайней мере Xorg с нею.
Вы могли ld_preload другая версия malloc, и добавлять поток для освобождения его после указанной суммы секунд. Я сомневаюсь, что это работало бы, хотя...
Вам была бы нужна эта работа: http://lattice.umiacs.umd.edu/files/functions_tr.pdf
Я думаю, что ulimit реализация сосет случайным образом почти в любой операционной системе. Я использовал ulimit-S-v на Linux в течение шести лет. Шесть! И кажется, что некоторые ядра не поддерживают его больше. Я получил Mac, и OS X 10.6 не поддерживает его. Я также попробовал-m. В моем старом рабочем столе с Ubuntu 9.04 ulimit-S хорошо работает-v.
Действительно, я ищу действительное решение этого. Я просто не могу верить людям в Apple, например, позволить их программе взбеситься на памяти.