Использование памяти Ruby стало безумным - PullRequest
0 голосов
/ 06 ноября 2018

От поставщика данных я загружаю примерно 75 изображений + 40 страниц деталей за одно задание, используя RestClient.

Идет так:

  1. Аутентифицироваться поставщику услуг и установить банку печенья в переменной
  2. Скачать XML
  3. XML содержит примерно 40 активов.
  4. Для каждого актива скачать список изображений. (От 0 до 10 изображений на один актив).
  5. Загрузка изображений.

Мой общий размер загрузки составляет 148,14 МБ за 37,58 секунд, через 115 уникальных запросов. Мое потребление памяти:

Total allocated: 1165532095 bytes (295682 objects)
Total retained:  43483 bytes (212 objects)

измерено с memory_profiler драгоценным камнем. Это чуть больше 1 ГБ памяти для загрузки ~ 150 МБ данных?

Моя большая проблема в том, что мне нужно загрузить еще больше данных - это всего лишь 1 из 15 дней данных. Когда я запускаю данные за 2 дня, я удваиваю размер загрузки и объем памяти. При работе с данными за 3 дня я утраиваюсь и т. Д. Это даже выглядит так, что потребление памяти увеличивается экспоненциально, пока у меня не кончится память и мой сервер не работает.

Почему здесь не запускается сборщик мусора? Я пробовал запускать GC.start между каждым днем ​​загружаемых данных, трюками memory_profiler, но мой сервер все равно заканчивал сбоем, когда я добавлял слишком много дней данных.

Итак, мой вопрос:

  1. Почему потребление памяти так высоко по сравнению с данными, которые я на самом деле загружаю.
  2. Поскольку я перезаписываю переменные, хранящие загруженные данные, между каждой загрузкой, должна ли сборка мусора не очищать память предыдущей загрузки данных?
  3. Какие-нибудь советы и хитрости, чтобы уменьшить потребление памяти?

Версии: Ruby: 2.4.4p296 , RestClient: 2.0.2 , ОС: Ubuntu 16.04

Пример кода:

Использование RestClient: https://gist.github.com/mtrolle/96f55822122ecabd3cc46190a6dc18a5

Использование HTTParty: https://gist.github.com/mtrolle/dbd2cdf70f77a83b4178971aa79b6292

Спасибо

1 Ответ

0 голосов
/ 01 декабря 2018

Полагаю, все дело в используемом вами http-клиенте: Rest-Client. К сожалению, у него плохая репутация жаждущего памяти. Вам определенно стоит поискать какой-нибудь удивительный драгоценный камень, который экономит память и время 1003 *.

Я очень рекомендую HTTP.rb или его преемник http / 2 HTTPX

Для хорошего теста, пожалуйста, взгляните на эту удивительную статью автора другого удивительного камня Shrine : https://twin.github.io/httprb-is-great/

Вот что я нашел после замены Rest-Client на HTTP-файл на моем локальном компьютере:

Версии: Ruby: 2.5.3p105, HTTP.rb: 4.0.0, ОС: Ubuntu 16.04

Общий размер загрузки: 96,92 МБ через 118 уникальных запросов.

Потребление памяти:

Total allocated: 7107283 bytes (83437 objects)
Total retained:  44221 bytes (385 objects)

Таким образом, при загрузке было выделено 7Mb 96.92Mb по сравнению примерно с 1Gb при использовании Rest-Client.

Вот фрагмент: https://gist.github.com/mtrolle/96f55822122ecabd3cc46190a6dc18a5#gistcomment-2774405

...