Вы справляетесь с условиями нехватки памяти?

9

Что вы делаете, когда mallocвозвращает 0 или исключение новых бросков? Просто остановить или попытаться выжить в состоянии OOM / сохранить работу пользователя?

МБк
источник
4
Связано с Stackoverflow stackoverflow.com/questions/763159/…
ysolik
11
Argh. Я продолжаю читать это как "из маны". Думаю, в моем прошлом слишком много видеоигр. :)
Адам Лир

Ответы:

4

Я бы избежал ООМ, как избежать крушения.

Старайтесь не выполнять огромную часть работы (и выделять огромную часть памяти) сразу. Сохраняйте данные на диске, доверяйте кешу диска ОС и максимально используйте отображенный в памяти ввод-вывод и работайте только с небольшой частью данных одновременно. Если большие объемы данных должны находиться в режиме онлайн (обслуживаться с низкой задержкой), сохраняйте их в памяти на нескольких компьютерах, как это делают все крупные поисковые системы. Или купить SSD.

rwong
источник
Видимо, это имеет смысл больше всего.
МБк
2
Был большой спор о том, как правильно обрабатывать OOM (RAII, безопасность исключений, бла ...), но однажды я понял, что в многопоточной системе с несколькими динамическими модулями (некоторые из сторонних), даже если ваш поток не сделал сбой, есть момент неудачного времени, когда каждый поток увидит OOM. Если хотя бы один из них решил пойти дальше, вы ничего не можете сделать, кроме свидетелей.
rwong
13

Большинство людей, отвечающих на этот вопрос, вероятно, никогда не работали на встроенных системах, где malloc возвращает 0 - вполне реальная возможность. В системе, над которой я сейчас работаю, имеется 4,25 КБ ОЗУ (это 4352 байта). Я выделяю 64 байта для стека, и в настоящее время у меня есть куча 1600 байтов. Буквально вчера я отлаживал процедуру обхода кучи, чтобы следить за распределением и освобождением памяти. Ход кучи использует небольшой (30 байт) статически выделенный буфер для вывода на последовательный порт. Это будет отключено для версии выпуска.

Так как это потребительский продукт, лучше не исчерпывать память после выпуска продукта. Я уверен, что это будет во время разработки. В любом случае, все, что я могу сделать, это пару раз подать звуковой сигнал на динамик и вызвать перезагрузку.

tcrosley
источник
2
Функциональность в небольшом пространстве удивительна ... это такая форма искусства, как бонсай
rwong
6
Многие проекты на встроенных системах просто запрещают динамическое выделение памяти. Единственным случаем OOM остается переполнение стека.
Mouviciel
Вы правы, но особенно с вашим первым предложением: большая часть этого просто не имеет отношения к большинству разработчиков к счастью.
Конрад Рудольф
4

Честно говоря, во всех проектах, которые я делал (имейте в виду, что я еще нигде не работаю), я никогда не думал, что это может произойти, и поэтому я полагаю, что мои программы умрут очень быстро.

Кроме того, обработка OOM требует, чтобы вы предварительно распределили ресурсы для отображения сообщения об ошибке или для сохранения всего, что может быть неудобно.

Я чувствую, что в наши дни память стоит меньше, чем арахис, это не должно случаться часто. На заре защищенной памяти и раньше, может быть, это было проблемой, но сейчас? Единственные ошибки OOM, которые я когда-либо видел, были из ошибочного кода.

zneak
источник
Я могу подумать о том, чтобы восстановить часть памяти, уже имеющейся в процессе, и попытаться либо выжить и восстановиться (трудно, если вы сбросили что-нибудь полезное), либо выжить как данные + остатки, которые пытаются его сохранить.
барбекю
2

Проверка кодов возврата malloc обычно бессмысленна.

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

Пока вы не запишите в память физическую, уникальную страницу, выделенную для ваших процессов. Если это распределение не удастся, ядро ​​завершит процесс (возможно, ваш!) В попытке найти память. В этот момент вы больше ничего не можете сделать.

Кристоф Провост
источник
У меня была идея, чтобы войти в цикл while с долгим сном внутри - и, возможно, восстановить, если процесс переживет убийцу OOM. У меня сложилось впечатление, что процессы были довольно прерваны из-за его попытки использовать адрес 0, но я не провел никаких серьезных тестов.
МБк
Вам не нужно делать ничего особенного, чтобы иметь дело с убийцей OOM. Если ваш процесс вызвал его, но не был выбран, он никогда не узнает. Все будет работать так, как если бы было достаточно памяти. С другой стороны, если ваш процесс выбран, он будет прерван, и вы ничего не можете с этим поделать.
Кристоф Провост
Но я могу попытаться подождать, пока OOM освободит память, а затем снова попытаться выделить и продолжить. У меня сложилось впечатление, что malloc / new не ждет, когда это произойдет.
МБк
Нет, ты не можешь. Ваше распределение всегда будет успешным. Вы получите всю виртуальную память, которую хотите. Физическая память не выделяется, пока вы не коснетесь ее. Как только вы коснетесь нераспределенной страницы, ваш процесс будет приостановлен. Ядро будет искать больше памяти, что может привести к остановке процесса для увеличения памяти. Если это удастся (и это не убьет вашу!), Страница будет выделена, и ваш процесс возобновится. Ваш процесс не может сказать, что это произошло.
Кристоф Провост
2
Я уверен, что окна никогда не перегружаются. Он может передавать больше, чем ОЗУ, но не больше, чем ОЗУ + файл подкачки.
CodesInChaos
2

Если вы не разрабатываете для встраиваемых систем, систем реального времени или систем, которые настолько критичны, что сбои могут стоить жизни или миллиарды долларов ... Тогда, вероятно, не стоит с финансовой точки зрения беспокоиться о нехватке памяти.

В большинстве случаев мало что можно сделать, когда у вас все равно не хватает памяти, поскольку нет памяти для создания каких-либо новых объектов или выполнения каких-либо задач, которые могут что-то сделать. Вы должны взвесить стоимость приложения, обрабатывающего OOM, и выгоду, которую вы получите от этого.

Эрик Фанкенбуш
источник
Системам реального времени не нужно проверять больше о сбое malloc, чем другим системам.
zneak
@zneak - Неверно. Системы реального времени должны быть предсказуемыми, а нехватка памяти - непредсказуемой, если вы специально не планируете это.
Эрик Фанкенбуш
Итак, что еще ты собираешься делать, когда попадешь в OOM?
zneak
Свободная память, отмена процессов и т. Д. Система реального времени обычно не имеет виртуальной памяти или системы подкачки, поскольку она должна быть детерминированной. Таким образом, он может быть намного проще из памяти.
Эрик Фанкенбуш
Учитывая определенный путь кода, который неизбежно приведет к ошибке OOM, я не вижу, как сбой является менее детерминированным подходом, чем освобождение памяти и отмена процессов.
2010 года
1

Я бы всегда проверял на ошибку. Если что-то возвращает условие ошибки, то это должно быть обработано вашей программой. Даже если это сообщение «Недостаточно памяти, надо идти!», Это лучше, чем «Нарушение доступа», «Дамп выгружен» или что-то еще. Одним из них является состояние ошибки, которое вы обрабатываете, другим является ошибка. И пользователь это тоже будет воспринимать.

В вашем конкретном случае вы можете попытаться откатить операцию, освободив ресурсы, которые вы выделили, до достижения точки сбоя, сообщив об ошибке и продолжив выполнение (возможно, когда вы пытаетесь выйти из приложения, вы можете дать возможность выйти сразу). Таким образом, пользователь может решить, что делать, или попытаться высвободить часть памяти, поигравшись, закрыв файлы и т. Д. Конечно, то, как вы справитесь с ситуацией, сильно зависит от вашей программы - программы, которая не должна быть интерактивным, вероятно, просто нужно зарегистрировать ошибку и либо выйти, либо продолжить.

Dysaster
источник