Подтвердить что ты не робот

Каковы ваши стратегии, чтобы поддерживать низкий уровень использования памяти?

Ruby действительно голодна, но также стоит каждого отдельного бита.

Что вы делаете, чтобы поддерживать низкий уровень использования памяти? Вы избегаете больших строк и вместо этого используете меньшие массивы/хеши или вам не о чем беспокоиться, и пусть сборщик мусора выполняет эту работу?

Изменить. Я нашел хорошую статью по этому вопросу здесь - старый, но все же интересный.

4b9b3361

Ответ 1

  • Выберите структуры дат, которые являются эффективными представлениями, хорошо масштабируются и делают то, что вам нужно.
  • Используйте алгоритмы, которые работают с использованием эффективных структур данных, а не раздуты, но проще.
  • Посмотрите еще где. Ruby имеет мост C, и его гораздо легче запоминать память в C, чем в Ruby.

Ответ 2

Я нашел Phusion Ruby Enterprise Edition (вилка mainline Ruby с значительно улучшенной сборкой мусора), чтобы внести существенный вклад в использование памяти... Кроме того, они сделали его чрезвычайно простым в установке (и для удаления, если вы найдете необходимость).

Вы можете узнать больше и загрузить его на их веб-сайт.

Ответ 3

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

Если у вас есть приложение, где память будет лимитирующим фактором, то Ruby может и не быть лучшим выбором. Тем не менее, я обнаружил, что мои приложения Rails обычно потребляют около 40-60 МБ оперативной памяти на экземпляр Mongrel. В схеме вещей это не очень много.

Возможно, вы сможете запускать свое приложение на JVM с помощью JRuby - Ruby VM в настоящее время не так продвинута, как JVM для управления памятью и сбора мусора. В выпуске 1.9 добавлено много улучшений, и в разработке также есть альтернативная VM.

Ответ 4

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

Имейте в виду, что ruby ​​выделяет объекты, например, что-то простое, как

100.times{ 'foo' }

выделяет 100 строковых объектов (строки изменяемы и каждая версия требует собственного выделения памяти).

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

Создание хеш-объекта действительно выделяет больше, чем объект, например

{'joe' => 'male', 'jane' => 'female'}

не выделяет 1 объект, кроме 7. (один хеш, 4 строки + 2 строки)

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

Пример: Где-то в вашем приложении вы применяете to_sym для имени пользователя, например:

hash[current_user.name.to_sym] = something

Когда у вас сотни пользователей, это может быть хорошо, но что происходит, если у вас есть миллион пользователей? Вот цифры:

ruby-1.9.2-head >
# Current memory usage : 6608K
# Now, add one million randomly generated short symbols
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s).to_sym }

# Current memory usage : 153M, even after a Garbage collector run.

# Now, imagine if symbols are just 20x longer than that ?
ruby-1.9.2-head > 1000000.times { (Time.now.to_f.to_s * 20).to_sym }
# Current memory usage : 501M

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

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

Вот некоторые ссылки в отношении:

http://merbist.com

http://blog.monitis.com

Ответ 5

Я не разработчик ruby, но я думаю, что некоторые методы и методы верны для любого языка:

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

Использовать корректную (попробуйте уловить) обработку ошибок, чтобы убедиться, что объекты и соединения закрыты

Когда работа с наборами данных возвращает только минимально необходимый

Ответ 6

  • При развертывании веб-приложения Rails/Rack используйте REE или другой дружественный интерпретатор для копирования на запись.
  • Извлеките сборщик мусора (см. http://www.engineyard.com/blog/2011/tuning-the-garbage-collector-with-ruby-1-9-2/, например)
  • Попробуйте сократить количество внешних библиотек/драгоценных камней, которые вы используете, поскольку дополнительный код использует память.
  • Если у вас есть часть приложения, которое действительно интенсивно использует память, возможно, стоит переписать его на расширение C или завершить его, вызывая другие/быстрее/лучше оптимизированные программы (если вам приходится обрабатывать огромное количество текстовых данных, возможно, вы можете заменить этот код на вызовы grep, awk, sed и т.д.)

Ответ 7

Кроме того, в экстремальных случаях использование памяти не стоит беспокоиться. Время, затрачиваемое на сокращение использования памяти, выберет LOT гигабайт.

Ответ 8

Взгляните на Программное обеспечение малой памяти - шаблоны для систем с ограниченной памятью. Вы не указываете, какое ограничение памяти, но я предполагаю RAM. Хотя я и не настроен на Ruby, я думаю, вы найдете в этой книге полезные идеи: шаблоны охватывают RAM, ROM и вторичное хранилище и делятся на основные методы небольших структур данных, распределения памяти, сжатия, вторичного хранилища и небольших архитектура.

Ответ 9

Единственное, что мы когда-либо имели, о чем стоит беспокоиться, это RMagick.

Решение состоит в том, чтобы убедиться, что вы используете RMagick версии 2 и вызываете Image#destroy!, когда вы закончите использовать свое изображение

Ответ 10

Избегайте такого кода:

str = ''
veryLargeArray.each do |foo|
  str += foo
  # but str << foo is fine (read update below)
end

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

Вместо этого используйте Array#join:

str = veryLargeArray.join('')

Это реализовано на C очень эффективно и не несет накладных расходов на создание строк.

ОБНОВЛЕНИЕ: Джонас прав в комментарии ниже. Мое предупреждение сохраняется для +=, но не <<.

Ответ 11

Я новичок в Ruby, но до сих пор я не счел нужным делать что-то особенное в этом отношении (то есть помимо того, что я обычно делаю как программист вообще). Возможно, это потому, что память дешевле, чем время, которое потребуется для серьезной оптимизации для нее (мой код Ruby работает на машинах с 4-12 ГБ ОЗУ). Это также может быть связано с тем, что задания, которые я использую для этого, не являются долговременными (т.е. Они будут зависеть от вашего приложения).

Ответ 12

Я использую Python, но я думаю, что стратегии похожи.

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

В больших функциях/методах я явно удаляю большие временные объекты (например, списки), когда они больше не нужны. Закрытие ресурсов как можно раньше может помочь.

Ответ 13

Что-то, о чем нужно помнить, - это жизненный цикл ваших объектов. Если вы объекты не так много обошлись, сборщик мусора в конце концов ударит и освободит их. Однако, если вы продолжаете ссылаться на них, может потребоваться несколько циклов для сборщика мусора, чтобы освободить их. Это особенно верно в Ruby 1.8, где сборщик мусора использует плохую реализацию техники маркировки и развертки.

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

Ответ 14

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

Будьте осторожны при использовании методов gem/library. Они не могут быть оптимизированы по памяти. Например, класс Ruby PG:: Result имеет метод "значения", который не оптимизирован. Он будет использовать много дополнительной памяти. Я еще не сообщал об этом.

Ответ 16

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

В случаях, когда вы должны прочитать какой-то огромный набор данных из базы данных, обязательно прочитайте в режиме "вперед/назад" и обработайте его небольшими битами, а затем сначала загрузите все в память.

Ответ 17

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