Чи обробляєте Ви умови пам'яті?


9

Що ви робите, коли mallocповертається 0 або викиди нових кидків? Просто зупиніть або спробуйте пережити стан OOM / зберегти роботу користувача?


4
Пов'язані з Stackoverflow stackoverflow.com/questions/763159 / ...
ysolik

11
Арг. Я продовжую читати це як "поза маною". Думаю, занадто багато відеоігор у моєму минулому. :)
Адам Лір

Відповіді:


4

Я уникав би OOM, як уникнути аварії.

Уникайте робити величезну частину роботи (і виділяти величезну частину пам'яті) відразу. Зберігайте дані на диску, довіряйте кеш диска ОС і максимально використовуйте IO, відображений на пам'яті, і працюйте лише з невеликою частиною даних одночасно. Якщо великі обсяги даних потребують он-лайн (подаються з низькою затримкою), то зберігайте їх у пам'яті на кількох машинах, як це роблять усі великі пошукові компанії. Або придбати SSD.


Мабуть, це має сенс найбільше.
mbq

2
Була велика дискусія щодо того, як грамотно поводитися з OOM (RAII, безпека винятків, blah ...), але одного разу я зрозумів, що в багатопотоковій системі з декількома динамічними модулями (деякі з сторонніх), навіть якщо ваша нитка не крах, є момент нещасного часу, коли кожен потік побачить ОМУ. Якщо навіть один вирішив іти вперед, ви нічого не можете зробити, окрім очевидців.
rwong

13

Більшість людей, які відповідають на це питання, напевно, ніколи не працювали над вбудованими системами, де повернення malloc 0 є реальною можливістю. У системі, над якою я зараз працюю, є всього 4,25 Кбайт оперативної пам’яті (це 4352 байти). Я виділяю 64 байти для стека, а в даний час маю 1600 байт. Лише вчора я налагоджував звичайну процедуру прогулянки купою, щоб я міг слідкувати за розподілом та звільненням пам’яті. Куповий прохід використовує невеликий (30 байт) статично виділений буфер для виведення на послідовний порт. Він буде вимкнено для версії версії.

Оскільки це споживчий продукт, то краще не вичерпати пам'ять, коли продукт буде випущений. Я впевнений, що буде під час розвитку. У будь-якому випадку, про все, що я можу зробити, це пролунати звуковий сигнал динаміка пару разів і примусити перезавантажити.


2
Встановлення функціональних можливостей всередині невеликого простору - дивовижне ... це такий вид мистецтва, як бонсай
rwong

6
Багато проектів у вбудованих системах просто забороняють динамічне розподіл пам'яті. Єдиним випадком OOM залишається переповнення стека.
mouviciel

Ви маєте рацію, але особливо з першим реченням: більшість цього просто не стосується більшості розробників на щастя.
Конрад Рудольф

4

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

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

Я відчуваю, що в ці дні пам’ять коштує менше, ніж арахіс, це не те, що має траплятися часто. На зорі захищеної пам’яті та раніше, можливо, це було турботою, але зараз? Єдині помилки OOM, які я коли-небудь бачив, були з помилкового коду.


Я можу подумати відновити частину пам'яті, яку вже має процес, і спробувати або вижити і відновити (важко, якщо ви скинули щось корисне), або вижити як дані + залишки, які намагаються зберегти його.
mbq

2

Перевірка кодів повернення malloc взагалі є безглуздим.

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

Це не поки ви не запишете в пам'ять, що фізична, унікальна сторінка виділяється для ваших процесів. Якщо цього розподілу не вдасться, ядро ​​припинить процес (можливо, ваш!) У спробі знайти пам'ять. На той момент більше нічого не можна робити.


У мене виникла ідея потрапити в петлю з довгим сном всередині - і, можливо, відновитись, якщо процес переживе вбивцю МОМ. У мене склалося враження, що процеси були досить припинені через його спробу використовувати 0 адресу, але я не робив жодних надійних тестів.
mbq

Вам не потрібно робити нічого особливого для боротьби з вбивцею OOM. Якщо ваш процес запустив його, але він не був обраний, він ніколи не дізнається. Все просто працюватиме так, ніби пам’яті вистачало. Якщо з іншого боку обраний ваш процес, він буде припинено, і ви нічого з цим не можете зробити.
Крістоф Простой

Але я можу спробувати зачекати, коли OOM звільнить деяку пам’ять, а потім спробувати виділити знову і продовжити. У мене таке враження, що malloc / new не чекає цього.
mbq

Ні, ти не можеш. Виділення завжди буде успішним. Ви отримаєте всю потрібну віртуальну пам'ять. Тільки доки не торкнешся, що фізична пам'ять виділяється. Як тільки ви торкаєтесь нерозподіленої сторінки, ваш процес призупиняється. Ядро шукатиме більше пам’яті, що може призвести до того, щоб знищити процес для отримання більшої кількості пам’яті. Якщо це вдасться (і це не вб'є ваше!), Сторінка буде виділена, і ваш процес відновиться. У вашому процесі немає жодного способу сказати, що це сталося.
Крістоф Простой

2
Я впевнений, що Windows ніколи не переборює. Він може здійснювати більше оперативної пам'яті, але не більше RAM + swapfile.
CodesInChaos

2

Якщо ви не розробляєте для вбудованих систем, систем у режимі реального часу або систем, які є настільки критичними, що збої можуть коштувати життя або мільярди доларів ... Тоді, мабуть, не варто цього турбуватися з-за умов пам'яті.

У більшості випадків мало що можна зробити, коли у вас все одно немає пам’яті, оскільки немає пам'яті для створення нових об’єктів або виконання будь-яких завдань, які можуть щось робити. Ви повинні зважити вартість роботи програми з OOM порівняно з вигодою, яку ви отримаєте від цього.


Системам у режимі реального часу не потрібно перевіряти більше про аварійний зрив, ніж інші системи.
zneak

@zneak - Неправда. Системи в режимі реального часу повинні бути передбачуваними, а пам’ять не передбачувана, якщо ви спеціально не плануєте цього.
Ерік Функенбуш

Отже, що ще ви збираєтеся робити, коли потрапите на УМН?
zneak

Вільна пам'ять, скасування процесів тощо. Система в режимі реального часу зазвичай не має віртуальної пам’яті або системи своп, оскільки вона має бути детермінованою. Отже, це може набагато легше вичерпати пам'ять.
Ерік Функенбуш

Враховуючи певний шлях коду, який неминуче призведе до помилки OOM, я не бачу, наскільки збої є менш детермінованим підходом, ніж звільнення пам'яті та скасування процесів.
zneak

1

Я завжди перевіряв би на помилку. Якщо щось повертає стан помилки, тоді це має вирішувати ваша програма. Навіть якщо це повідомлення, яке говорить: "З пам’яті, треба йти!", Це краще, ніж "Порушення доступу", "Ядро скинуто" чи будь-що інше. Один - це помилка, з якою ви працюєте, інший - помилка. І користувач сприйме це як таке.

У конкретному випадку ви можете спробувати відмовити операцію, звільнивши виділені ресурси до досягнення збою, повідомивши про помилку та продовжуючи виконання (можливо, коли ви намагаєтеся вийти з програми, ви можете надати можливість негайно вийти). Таким чином, користувач може вирішити, що робити, або спробувати звільнити деяку пам'ять, обертаючись, закриваючи файли і т. Д. Звичайно, як виправити ситуацію, сильно залежить від вашої програми - програми, яка не повинна бути інтерактивним, ймовірно, потрібно просто зареєструвати помилку і або вийти, або продовжити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.