LINUX.ORG.RU

Вопрос про выделение памяти в linux, виртуальную память, своп и т.п.


0

1

А что будет, если я задам стратегию выделения памяти, позволяющую выделить памяти больше, чем доступно (включая своп) и вдобавок к этому ещё и начную всю её юзать?

Допустим, заботливый админ поставил всякие там клёвые overcommit_memory, а моё приложение попытается выделить 80Гб (при этом вся оператива + своп = 40Гб, например) и это пройдёт успешно. По логике, если ОС выдала память, то она согласилась на её использование моим приложением. А как оно будет выкручиваться, когда к этой памяти пойдёт реальное обращение?

Что будет с приложением? Его прибьют? А за что формально? Ведь ранее со стороны ОС было дано согласие на использование 80Гб.

Или что с приложением произойдёт?

p.s. вопрос не касается другого моего топика про менеджер памяти, там немного про другое.

Его прибьют?

Да.

А за что формально?

Ибо нефиг. Или тебе требуется судебное решение?

Никто вообще не гарантирует, что твоё приложение, пусть даже самое правильное на свете, проживёт хоть сколько-нибудь. Может сгореть компьютер, ядро выдать панику, кончиться память, прийти злой админ с kill -KILL $pid, случиться землятрясение и т.п.

Ведь ранее со стороны ОС было дано согласие на использование 80Гб.

Ты как-то странно интерпретируешь суть вызова mmap.

geekless ★★
()
Последнее исправление: geekless (всего исправлений: 2)
Ответ на: комментарий от geekless

Я вообще не в курсе, что любой new() или malloc() сводится к вызову mmap.

А как правильно интерпретировать то, что malloc() (пускай за ним стоит mmap) вернул мне ненулевой указатель? У меня одна интерпретация - система пошарилась по закромам и нашла мне столько байт, сколько я попросил. Иначе, вернула бы 0. Иначе получается, что я могу попросить 8192 байт, а мне могут дать 4096. Откуда мне знать, что там всего половина? Это наркоманское программирование... Нет?

kiverattes ★☆
() автор топика
Последнее исправление: kiverattes (всего исправлений: 1)

четай модераторов: http://catap.ru/blog/2009/05/05/about-memory-overcommit-memory/

в предыдущем твоем треде притащил прогу: C++. Предсказуемость поведения менеджера памяти. (комментарий)

запусти, скажи какой выхлоп видишь, приложи к этому cat /proc/meminfo и free -m :)

stevejobs ★★★★☆
()
Ответ на: комментарий от kiverattes

А как правильно интерпретировать то, что malloc() (пускай за ним стоит mmap) вернул мне ненулевой указатель? У меня одна интерпретация - система пошарилась по закромам и нашла мне столько байт, сколько я попросил.

malloc означает, что тебе выдали память из кучи. Мы про семантику malloc или mmap?

Откуда мне знать, что там всего половина? Это наркоманское программирование... Нет?

А откуда ты можешь знать, что в следующее мгновение пользователь не нажмёт reset? Ниоткуда. Это наркоманское программирование?

Поставим вопрос иначе: а откуда системе знать, сколько у ней будет памяти для тебя? Ты сказал, что тебе надо N килобайт, система запомнила. Если у ней будет в наличии, когда ты будешь этой памятью пользоваться — тебе дадут. А нет — ну значит не повезло.

geekless ★★
()

Если у тебя физической памяти 40ГБ, то 80ГБ тебе не выделят. malloc вернёт ноль, new кинет bad_alloc.

Допустим у тебя 40ГБ, а ты выделяешь 39. Тогда пройдёт. Как только ты начинаешь писать в какие-либо адреса, происходять сегфолты, но ты их не видишь. Их ядро перехватывает и видя, что ты раньше сделал new 39GB выделяет тебе страницу из первых попавшихся свободных.

Допустим так было да 20го ГБ. Потом ты запустил фаейрфокс посмотерть вконтактик. Смотришь себе, а твоя програмка хавает и хавает страницы.

И вот дошла она (програмка) до 33ГБ, а твой вконтактик 7 уже захавал и свободных страниц у ядра нет. Тогда ядро запускает oom killer, который будет убивать не твою програмку, а вконтактик. Или любой другой процесс, который по мнению оом киллера «нинужен». А програмку твою никто убивать не станет, и она спокойно схавает 39ГБ страниц, как и было обещано ядром.

Другое дело, что от деятельности оом киллера чего-то там в системе слететь может, из-за чего твоя програмка не сможет нормально ф-ть. Но это уже другая история.

nanoolinux ★★★★
()
Ответ на: комментарий от geekless

Его прибьют?

Да.

Я вооще-то где-то читал, что как раз наоборот. оомкиллер других будет убивать, но не процесс, который память просил. Ссылка почитать есть?

nanoolinux ★★★★
()
Ответ на: комментарий от kiverattes

что любой new() или malloc() сводится к вызову mmap

malloc вызывает либо sbrk(2), либо mmap(2)

stevejobs ★★★★☆
()
Ответ на: комментарий от nanoolinux

Я так понял, всякие overcommit_memory позволяют задать стратегию, позволяющую выделить больше, чем есть физической + свопа. Нет?

kiverattes ★☆
() автор топика

Если повезет, придет oom-killer и начнет расстрел с самых жирных. Если не повезет (а эта ситуация бывала в 99% случаев на старых ведрах), система просто повиснет. Наглухо.

Anon
()
Ответ на: комментарий от kiverattes

система пошарилась по закромам и нашла мне столько байт

Вот тут вопрос байт чего она нашла, фактически - виртуального адресного пространства, а не реальной памяти.

Begemoth ★★★★★
()

История повторяется. N лет назад тут был товарищ любивший поговорить о кунилингусе и «анекдотах на Си». А ведь все началось с «клёвые overcommit_memory» и утверждения, что после malloc() не надо проверять результат, т.к. есть или нет реально память, ОС оптимистично выдаст ответ «ОК, на тебе память»

sdio ★★★★★
()
Ответ на: комментарий от kiverattes

Бульбец! Ну вот ты бы уже 100500 раз прочел все, что нужно. А так долбишь мозги и себе, и людям!

Представь себе стратегию: ты занимаешь у человека 50т.р., но тебе все сразу не нужны, и ты потихоньку тягаешь, а он в блокнотике записывает, сколько ты уже взял. Вот, скажем, есть у человека 35т.р. А ты уже 30 натягал. Приходишь в очередной раз за 10т.р. И тут возможны ситуации: либо ему кто-то уже дал n-ю сумму, в результате чего у него есть ≥10т.р., либо хрен. Во втором случае он тебе говорит: или позже приходи, или ПНХ. В первом — дает сумму, как ни в чем не бывало.

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

Если же ты скажешь этому человеку: "мне нужна вся сумма сразу, но не больше, чем у тебя есть", то ситуация будет мягче. Он просто пошлет тебя, если этой суммы не будет.

Anon
()
Ответ на: комментарий от nanoolinux

Да, про «невидимые сегфолты» понимаю - кодил под protected mode 386, там есть исключения всякие на тему доступа к памяти, которые можно обрабатывать путём организации всяких свопов на дисках...

Про oom killer интересно. Насчёт «обещано ядром» не понял. Под обещано я бы понял «выделено», а кто приложению обещал 39 Гб до того, как оно хотя-бы предприняло попытку их выделить?

kiverattes ★☆
() автор топика
Ответ на: комментарий от sdio

Про «не надо проверять результат» я ещё не успел сказать. Я так не считаю )

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Под обещано я бы понял «выделено», а кто приложению обещал 39 Гб до того, как оно хотя-бы предприняло попытку их выделить?

Во-первых, очень редко бывает, что приложению реально нужна вся память, которую оно просит. Во-вторых, если оно действительно столько жрет, то к моменту, когда понадобится все, вполне возможно, что память освободится. Ну, или вся надежда на oom-killer'а.

Anon
()
Ответ на: комментарий от sdio

Да месяца 4 назад какой-то залётный тролль тоже рассказывал про «после malloc() не надо проверять результат»...

geekless ★★
()
Последнее исправление: geekless (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Это понятно, что виртуальной. Вопрос в другом - там товарищ утверждает, что кроме вариантов «выделено» и «не выделено» существует третий «выделено, но меньше чем запрошено».

kiverattes ★☆
() автор топика
Последнее исправление: kiverattes (всего исправлений: 1)
Ответ на: комментарий от kiverattes

Да, про «невидимые сегфолты» понимаю - кодил под protected mode 386, там есть исключения всякие на тему доступа к памяти, которые можно обрабатывать путём организации всяких свопов на дисках...

Более косноязычного изложения идеи page fault я в жизни не слышал :D

geekless ★★
()
Ответ на: комментарий от kiverattes

Блин, ну почитай же ты, наконец, что тебе пичкают!

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

Аналогия: попробуй-ка на винте с 1ГБ свободного места создай терабайтный файл. Он создастся. Но по мере записи туда данных, если ты порнушку не поудаляешь, наступит момент, когда место внезапно кончится. Ты тоже будешь спрашивать: "ай-яй-яй, как же так? У меня ведь на 140-гигабайтном винте был уже создан терабайтный файлик, а вдруг место кончилось…"

Anon
()
Ответ на: комментарий от Anon

Про «подгружаются новые страницы» - понятно. Обычный механизм функционирования виртуальной памяти. Ясно, что не всё, что мне выделено, я смогу использовать, особенно при overcommit_memory.

Вопрос в другом. Где-то выше товарищ написал, что если я запросил N байт, то ВЫДЕЛИТЬ мне могут меньше. Вот от этого я окуел. То, что использовать я всю выделенную память не смогу - это ещё ладно, входит в понятие виртуальной памяти, но что на запрос N байт мне могут ВЫДЕЛИТЬ (виртуальной памяти) меньше, чем я просил - это сурово. Либо я не так понял человека.

kiverattes ★☆
() автор топика
Ответ на: комментарий от Anon

Это был ты! Я нашёл этот коммент: C++. Предсказуемость поведения менеджера памяти. (комментарий)

Я понял твой коммент так, что malloc() может выделить виртуальной памяти меньше, чем запрошено. А ты видимо имел ввиду, что физической будет меньше, чем запрошено - это как раз ясно, механизм выделения памяти ведь виртуальный...

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Если отбросить всю юзерспейсную шелуху в виде malloc/new, останутся используемые ими mmap и brk/sbrk (которые тот же ммап, только не для произвольных областей, а диапазон от фиксированной базы). Так вот ядро при ммапе помечает страницы в таблице страниц процесса флагом «выдать по необходимости», то есть при доступе к адресам страницы. То есть для страницы в адресном пространстве всего два режима: «выдать по необходимости» и «незамаплена вообще». Этим и отличается скрытый подгружающий сегфолт от явного. При включенном оверкоммите в системе возможна ситуация, когда количество таким образом помеченных (якобы выданных) страниц больше, чем количество физических страниц + страниц в свопе. Если вдруг все процессы активно начинают использовать свои страницы, наступает момент, когда доступных реальных страниц больше нет и кто-то должен умереть. При выключенном/нереализованном оверкоммите mmap просто вернет ошибку, если прямо сейчас нет столько страниц, то есть доступные страницы резервируются моментально, а не оптимистично.

Надо понимать, что виртуальное адресное пространство процесса не совпадает с физическим (в этом суть memory mapping) и кусок памяти процесса может время от времени плавать по физическим адресам и свопу, абсолютно прозрачно для процесса.

arturpub ★★
()
Ответ на: комментарий от kiverattes

Ну вот, ты меня немного недопонял. Тебе никогда не выделяют сразу столько, сколько ты просил. Память выделяется по мере ее заполнения. А вот ежели она "внезапно" кончилась, а тебе еще недодали, то получится забавная ситуация.

Anon
()
Ответ на: комментарий от Anon

Я всё-таки настаиваю на другой формулировке. Выделяется - это слово, которым мы описываем работу new(), malloc(). Эти функции работают с виртуальной памятью. А виртуальная выделяется либо вся сразу (запрошенная), либо не выделяется вообще.

А уж как эта виртуальная память будет обеспечена физической и будет ли вообще - это другой контекст разговора. Конексты путаются.

kiverattes ★☆
() автор топика
Ответ на: комментарий от arturpub

Понимание этого имеется. Аналогия с банками и кредитами, мать их за ногу, была бы уместной )

kiverattes ★☆
() автор топика

Что будет с приложением? Его прибьют? А за что формально? Ведь ранее со стороны ОС было дано согласие на использование 80Гб.

Да даже если ты и 39 попросишь при максимуме в 40, админ может в любой момент отключить своп, и через несколько секунд новый подключить. Количество доступной памяти ни разу не константа.

arturpub ★★
()
Ответ на: комментарий от kiverattes

А, ну тогда считай, что выделилось столько, сколько требовали, но обеспеченно было лишь столько, сколько есть.

Anon
()

>моё приложение попытается выделить 80Гб (при этом вся оператива + своп = 40Гб, например) и это пройдёт успешно.

|=0=>1

неправильное умозаключение.

dimon555 ★★★★★
()
Ответ на: комментарий от kiverattes

Д. Бовет, М. Чезати, 3-е издание, стр. 503, «Выделение страниц по требованию». Начинай читать оттуда.

nanoolinux ★★★★
()
Ответ на: комментарий от kiverattes

что-то не получилось у меня 80 гигабайт выделить ((

$ cat mem_tst.c 
#include <stdio.h> //printf
#include <stdlib.h> //malloc

#define CHUNK_MEM 4096

int main() {
    void *addr;
    size_t chunk_cnt = 1;

    while((addr = malloc(chunk_cnt * CHUNK_MEM)) != NULL) {
//        printf("%p memory allocated %zu\n", addr, chunk_cnt * CHUNK_MEM);
        free(addr);
        chunk_cnt += 1;
    }
    printf("memory allocated %zu\n", chunk_cnt * CHUNK_MEM);
    return 0;
}
dimon555 ★★★★★
()
Ответ на: комментарий от kiverattes

как тебе система даст 10 ГБ, если у неё всего 8 ГБ?

вот 10 процессам по 2 гига она даст, а как только 8 исчерпаете, кого-то прибьют

dimon555 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.