Как предварительно выделить память для процесса в Solaris?

StackOverflow https://stackoverflow.com/questions/127771

  •  02-07-2019
  •  | 
  •  

Вопрос

Моя проблема:

У меня есть сценарий Perl, который использует много памяти (ожидаемое поведение из-за кеширования).Но я заметил, что чем больше я кэширую, тем медленнее оно становится и большую часть времени процесс проводит в спящем режиме.

Я думал, что предварительное выделение памяти для процесса может повысить производительность.

Есть ли у кого-нибудь здесь идеи?

Обновлять:

Я думаю, что я не очень ясно выражаюсь здесь.Я поставлю вопрос более четко:

Я не ищу способы предварительного выделения памяти внутри Perl-скрипта.Не думаю, что это мне здесь сильно поможет.Что меня интересует, так это способ сообщить ОС о выделении X объема памяти для моего Perl-скрипта, чтобы ему не приходилось конкурировать с другими процессами, которые появятся позже.

Предположим, что я не могу избавиться от использования памяти.Хотя я тоже изучаю способы уменьшить это, но не ожидаю большого улучшения.К вашему сведению, я работаю на машине Solaris 10.

Это было полезно?

Решение

Из ваших сообщений и комментариев я понял следующее:

  • Ваша программа замедляется, когда увеличивается использование памяти
  • Ваша программа все чаще проводит время во сне, а не за вычислениями.

Наиболее вероятное объяснение:Спать означает ждать, пока ресурс станет доступным.В этом случае ресурсом скорее всего является память.Для проверки используйте команду vmstat 1.Посмотрите на колонку SR.Если оно постоянно превышает ~150, система отчаянно пытается освободить страницы для удовлетворения спроса.Это сопровождается высокой активностью в столбцах pi, po и fr.

Если это действительно так, лучшим выбором будет:

  • Обновите системную память в соответствии с потребностями
  • Уменьшите использование памяти до уровня, подходящего для используемой системы.

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

Другие советы

Из комментария:

Ограничения памяти не очень серьезные, но объем памяти легко увеличивается до ГБ, а когда у нас есть конкурирующие процессы за память, она становится очень медленной.Я хочу зарезервировать немного памяти у ОС, чтобы тряска была минимальной, даже когда приходит слишком много других процессов.Джагмаль

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

Вы можете «зарезервировать» память, но это не предотвратит треш.На самом деле, это может усугубить проблему, поскольку ОС не будет знать, используете ли вы память или просто сохраняете ее на будущее.

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

Некоторые вопросы, которые вы можете задать себе:

  • действительно ли мои структуры данных полезны для поставленной задачи?
  • мне действительно нужно так много кэшировать?
  • могу ли я через некоторое время выбросить кэшированные данные?
my @array;
$#array = 1_000_000; # pre-extend array to one million elements,
                     # http://perldoc.perl.org/perldata.html#Scalar-values

my %hash;
keys(%hash) = 8192; # pre-allocate hash buckets 
                    # (same documentation section)

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

Удачи!

-- Дуглас Хантер

Недавно я заново открыл для себя превосходный Рэндал Л.Статья Шварца это включает в себя предварительное выделение массива.Предполагая, что это ваша проблема, вы можете протестировать предварительное выделение с помощью вариации этого кода.Но обязательно проверьте результат.

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

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

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

Наконец, вы изучили модуль Memoize?Возможно, это не сразу применимо, но может стать источником идей.

Я еще не мог найти способ сделать это.

Но я узнал, что (см. этот подробности)

Память, выделенная под лексику (т.е.my () переменные) не могут быть восстановлены или повторно используются, даже если они выходят из области.Это зарезервировано в случае, если переменные вернутся в сферу действия.Память, выделенная для глобальных переменных, может быть использована повторно (в рамках вашей программы) с помощью Undef () ing и/или delete ().

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

Похоже, вы ищете предел или ulimit.Но я подозреваю, что это приведет к сбою сценария, превышающего лимит, а это, вероятно, не то, что вам нужно.

Лучшей идеей может быть совместное использование кэшированных данных между процессами.По моему опыту, помещение данных в базу данных или в файл работает хорошо.

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

Единственное, что вы можете сделать, это использовать зоны Solaris (контейнеры).
Вы можете поместить свой процесс в зону и выделить ему такие ресурсы, как ОЗУ и ЦП.
Вот две ссылки на некоторые уроки:

  1. Контейнеры Solaris: руководство
  2. Управление ресурсами зоны в ОС Solaris 10 08/07

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

Видеть Внутреннее устройство Соляриса:Поддержка нескольких размеров страниц для получения дополнительной информации о разнице, которую это имеет, и о том, как это сделать.

Посмотри на http://metacpan.org/pod/Devel::Size

Вы также можете встроить функцию c, чтобы сделать вышеописанное.

Насколько я знаю, вы не можете выделить память непосредственно из Perl.Вы можете обойти это, написав модуль XS или используя встроенную функцию C, как я уже упоминал.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top