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

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

У меня есть приложение Rails 2.3.10 со связкой. При запуске объем памяти довольно большой (300 МБ в режиме разработки).

Я хотел бы посмотреть, сколько памяти занимает каждый самолёт при запуске.

4b9b3361

Ответ 1

У нас возникла проблема, в которой наше основное приложение Rails без трафика или запросов имело размер 140 МБ при запуске.

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

  • с помощью rails new myappname создайте новое пустое приложение rails
  • Скопируйте Gemfile из основного проекта в этот новый проект рельсов
  • запустите bundle install, а затем rails server, чтобы обеспечить загрузку сервера rails и необходимость загрузки любых основных конфигураций.
  • Откройте Gemfile и, за исключением спецификации для rails gem, добавьте require: false в конце каждой строки. Убедитесь, что любые другие драгоценные камни, которые указаны с одним именем, но требуемые с помощью: require = > 'othergemname', используют более раннюю нотацию рубинового хеша, так что шаблон, соответствующий ниже, будет его поймать.
  • Запустите bundle install снова, чтобы восстановить Gemfile.lock
  • Создайте следующий script, который будет вручную использовать каждый камень, указанный в Gemfile, и регистрирует системную память, потребляемую процессом rails до и после.

    # require_and_profile.rb
    def require_and_profile(gemname = nil)
      unless gemname
        puts "%-20s: %10s | %10s" % ['gem','increment','total']
        return
      end
      # This is how to get memory of calling process in OS X, check host OS for variants
      memory_usage = `ps -o rss= -p #{Process.pid}`.to_i / 1024.0
      require gemname
      puts "%-20s: %10.2f | %10.2f" % [ gemname, (`ps -o rss= -p #{Process.pid}`.to_i / 1024.0 - memory_usage), (`ps -o rss= -p #{Process.pid}`.to_i / 1024.0)]
    end
    
    pattern = /^[^#]*gem[ ]*['"]([^,'"]*)['"][ ,~>0-9\.'"]*(:require[ => ]*['"]([^'"]*)['"][, ])?/
    
    require_and_profile
    File.open('Gemfile').each do |line|
      if line.match(pattern)
      if line.match(pattern)[3]
        require_and_profile line.match(pattern)[3]
      else
          require_and_profile line.match(pattern)[1]
        end
      end
    end
    
  • Запустите rails c

  • load 'require_and_profile.rb'
  • Результат показывает, сколько (в МБ) каждый камень добавляет к основному окну приложения (приращение) и каков общий след после включения драгоценного камня (всего).

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

Ответ 2

Существует более простой способ сделать это сейчас с отброшенной жемчужиной:

добавить в свой gemfile:

gem 'derailed', group: :development

затем в командной строке из корня приложений:

bundle exec derailed bundle:mem

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

Ответ 3

Я бы сделал это следующим образом:

  • Найдите место в комплекте, где требуются все драгоценные камни.
  • после того, как требуется каждый драгоценный камень, получите текущий счет объекта (c = 0; ObjectSpace.each_object { c += 1 })

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

Два оговорки:

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