2017-02-23 84 views
2

Операционные системы, такие как Linux, работают по принципу Copy-on-write, поэтому, даже если вы выделяете массив размером 100 ГБ, но используете только до 10 ГБ, вы будете использовать только 10 ГБ памяти. Итак, каков был бы недостаток создания такого большого массива? Однако я вижу преимущество, которое заключается в том, что вам не придется беспокоиться об использовании динамического массива, который будет иметь стоимость перераспределения.Каким будет недостаток создания массива действительно большого размера на 64-битных системах?

+0

Я не уверен, что копирование на запись имеет отношение к вашей способности выделять 100 ГБ. –

+0

Возможный недостаток: получение OOM-убитого без возможности отладки причины? –

+0

Почему бы и нет? В основном, когда вы выделяете 100 ГБ, вы занимаете только адресное пространство, которое много на 64-битной системе. Copy-on-write означает, что вы фактически не используете память, пока не коснетесь ее. – pythonic

ответ

3

Основным недостатком является то, что, делая это, вы делаете сильное предположение о том, как работают стандартные распределители библиотек и основные Linux-распределители. Фактически, распределители и базовая система не всегда работают, как вы упоминаете.

Теперь вы упомянули «копировать при написании», но то, что вы, скорее всего, действительно имеете в виду, представляет собой комбинацию ленивой страницы и overcommit. В зависимости от конфигурации это означает, что любая память, которую вы выделяете, но не касаетесь, не может считаться с ограничениями памяти и может не занимать физическую память.

Проблема в том, что это часто может не сработать. Например:

  • Многих распределители имеют режимы, где они касаются выделенной памяти, например, в режиме отладки, чтобы заполнить его с известной моделью, чтобы помочь диагностировать ссылки на неинициализированного памяти. Большинство распределителей касаются по крайней мере нескольких байтов перед выделенной областью для хранения метаданных, которые могут использоваться для освобождения. Таким образом, вы делаете сильное предположение о поведении распределителя, которое может сломаться.
  • Поведение overcommit Linux - totally configurable. На практике многие серверные пользователи Linux отключат его, чтобы уменьшить неопределенность и неустранимые проблемы, связанные с убийцей OOM. Таким образом, ваше утверждение о том, что Linux ведет себя лениво, верно только для некоторой конфигурации overcommit и false для других.
  • Вы можете предположить, что память выполняется в 4K кусках и корректирует ваш алгоритм вокруг этого. Тем не менее, системы имеют разные размеры страниц: 16K и 64K не редкость в качестве размеров базовых страниц, а x86 Linux-системы по умолчанию имеют transparent huge pages, поэтому вы действительно можете получать 2048 тысяч страниц, не осознавая этого! В этом случае вы можете завершить почти весь массив, в зависимости от вашего шаблона доступа.
  • Как упоминалось в комментариях, «режим отказа» для такого типа использования довольно низок. Вы думаете, что будете использовать только небольшую часть массива, но если вы в конечном итоге используете больше, чем может обрабатывать система, в лучшем случае вы можете получить сигнал к вашему приложению при некотором случайном доступе к новой странице, но больше убийца oom просто убьет на вашем компьютере другой случайный процесс.

Здесь я предполагаю, что вы используете что-то вроде malloc или new выделить массив, так как вы не упомянули mmap ИНГ непосредственно или что-нибудь.

+0

Я подразумевал mmap, конечно, – pythonic

+2

Нет, вы этого не сделали. – BeeOnRope

2

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

Попытка выделить большой объем памяти, следовательно, фактически является эффективным способом максимизации вероятности того, что операционная система не позволит вашей программе использовать память.

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

Существуют также проблемы, которые могут возникнуть из-за того, что операционные системы могут быть сконфигурированы для перехвата. Говоря кратко, это означает, что когда программа запрашивает память, операционная система сообщает программе, что выделение выполнено успешно, даже если операционная система не выделила ее. Впоследствии, когда программа ИСПОЛЬЗУЕТ эту память (как правило, записывает данные на нее), операционная система внезапно требуется, чтобы НАСТРОЙКА сделало память доступной. Если операционная система не может это сделать по какой-либо причине, это становится проблемой для программы (которая считает, что она имеет доступ к памяти, но операционная система предотвращает доступ). Обычно это приводит к некоторому условию ошибки, влияющему на выполнение программы (и часто приводит к завершению программы). Хотя проблемы, связанные с чрезмерной фиксацией, могут повлиять на любую программу, шансы значительно увеличиваются, когда программа выделяет большой объем памяти.

+0

Чтобы быть справедливым, пользователь не спрашивает, почему это плохо для _use_ большого объема памяти, но разумна ли стратегия выделения, но не использования (следовательно, не заполнения страниц). Большинство вышеприведенных причин не относятся к этому случаю, поскольку в этом процессе не используется больше физической памяти или сопоставленных виртуальных страниц по сравнению с альтернативой, которая распределяется более редко. В частности, обычные настройки «ulimit» здесь не собираются, только «ulimit -v» будет работать, и это довольно проблематично, поскольку оно не считается правильным. – BeeOnRope

+0

.... за исключением того, что выделение массива в 100 ГБ и использование только 10 ГБ (о котором спросила ОП) все равно передаст 100 ГБ. ОП не спрашивал о разреженном распределении, только разреженное использование (используя 1 часть в 10) блока, выделенного программой. – Peter

+0

В общем, в Linux он не фиксирует 100 ГБ. При первом доступе страницы совершаются по одному (или, возможно, небольшим группам с ошибкой для сопоставления файлов). Это трюк, который позволяет вам выделять массив, намного больший, чем ваша физическая память, плюс своп, пока вы не получаете доступ к нему. – BeeOnRope

Смежные вопросы