CLI для анализа свалки рубиновой кучи. Спасибо Сэму Шаффрану за идею и начальный код.
Добавьте эту строку в Gemfile вашего приложения:
gem 'heapy'
А затем выполнить:
$ bundle
Или установите его самостоятельно как:
$ gem install heapy
Запустите с двумя входами для вывода значений сегодня.
$ heapy diff tmp/yesterday.dump tmp/today_morning.dump
Allocated STRING 9991 objects of size 399640/491264 (in bytes) at: scratch.rb:24
Запустить с тремя входами, чтобы показать различие между первыми двумя, но только если объекты все еще сохраняются в третьем
$ heapy diff tmp/yesterday.dump tmp/today_morning.dump tmp/today_afternoon.dump
Retained STRING 9991 objects of size 399640/491264 (in bytes) at: scratch.rb:24
# ...
Пропустите имя выходного файла и объекты, присутствующие в сегодняшнем дне.
$ heapy diff tmp/yesterday.dump tmp/today.dump --output_diff=output.json
Allocated STRING 9991 objects of size 399640/491264 (in bytes) at: scratch.rb:24
# ...
Writing heap dump diff to output.json
Из -за того, как сборщик мусора в МРТ управляет объектами на рубиновой куче, heapy diff
может создавать неполные или неверные различия при следующих обстоятельствах:
GC.compact
, либо с включенной автоматической композицией, Heapy не может создавать точные различия, потому что объекты могут перемещаться в разные слоты кучи и будут выглядеть как вновь выделенные, даже если они не были. В целом, любой механизм, который перемещает существующие объекты из одного слота кучи в другой, будет недействительным отчеты DIFF. Всегда выключайте уплотнение, прежде чем взять спуск <after>
Heap.<after>
, если рубин выделяет их в слоты кучи, которые ранее были заняты различными объектами на свалке <before>
, и которые затем были связаны между обоими дампами. Чтобы свести к минимуму вероятность того, что это произойдет, запустить основной GC три или более раз между выбросами кучи может помочь в достижении выживших и, таким образом, стабилизировать кучу перед тем, как принять дифференциацию.Шаг 1) Создайте свалку кучи. Вы могли бы сделать это вручную. Или вы можете использовать инструмент, такой как Deared_benchmarks
Шаг 2) Как только вы получите свалку кучи, вы можете проанализировать его, используя этот CLI:
$ heapy read tmp/2015-10-01T10:18:59-05:00-heap.dump
Generation: nil object count: 209191
Generation: 14 object count: 407
Generation: 15 object count: 638
Generation: 16 object count: 748
Generation: 17 object count: 1023
Generation: 18 object count: 805
# ...
Примечание. Причина, по которой вы можете получить генерацию «нуль», заключается в том, что эти объекты были загружены в память, прежде чем ваш код начал отслеживать ассигнования. Чтобы убедиться, что все распределения отслеживаются, вы можете выполнить свой сценарий Ruby. Сначала создайте файл trace.rb
, который только начинает трассировку распределения:
# trace.rb
require 'objspace'
ObjectSpace.trace_object_allocations_start
Теперь убедитесь, что эта команда загружена перед запуск сценария, вы можете использовать Ruby's -I
, чтобы указать путь нагрузки и -r
, чтобы указать библиотеку, которая требуется, в данном случае наш файл трассировки
$ ruby -I ./ -r trace script_name.rb
Если последняя строка вашего файла недействительна JSON, убедитесь, что вы закрываете файл после написания к нему дамп рубиновой кучи.
Вы можете свернуть в определенное поколение. В предыдущем примере 17 -я поколение выглядит странно большим, вы можете сверлить в него:
$ heapy read tmp/2015-10-01T10:18:59-05:00-heap.dump 17
Analyzing Heap (Generation: 17)
-------------------------------
allocated by memory (44061517) (in bytes)
==============================
39908512 /app/vendor/ruby-2.2.3/lib/ruby/2.2.0/timeout.rb:79
1284993 /app/vendor/ruby-2.2.3/lib/ruby/2.2.0/openssl/buffering.rb:182
201068 /app/vendor/bundle/ruby/2.2.0/gems/json-1.8.3/lib/json/common.rb:223
189272 /app/vendor/bundle/ruby/2.2.0/gems/newrelic_rpm-3.13.2.302/lib/new_relic/agent/stats_engine/stats_hash.rb:39
172531 /app/vendor/ruby-2.2.3/lib/ruby/2.2.0/net/http/header.rb:172
92200 /app/vendor/bundle/ruby/2.2.0/gems/activesupport-4.2.3/lib/active_support/core_ext/numeric/conversions.rb:131
Вы можете ограничить выход, передавая значение --lines
:
$ heapy read tmp/2015-10-01T10:18:59-05:00-heap.dump 17 --lines=6
Примечание: значение строк по умолчанию составляет 50
Если вы хотите прочитать все поколения, вы можете использовать директиву «все»
$ heapy read tmp/2015-10-01T10:18:59-05:00-heap.dump all
Вы также можете использовать онлайн-анализатор на основе JS на основе JS для визуализации. Другой инструмент
После проверки репо, запустите $ bundle install
для установки зависимостей. Затем запустите rake spec
чтобы запустить тесты.
Чтобы установить этот драгоценный камень на локальную машину, запустите bundle exec rake install
. bundle exec rake release
выпустить .gem
версию, обновите номер версии в version.rb
.
Отчеты об ошибках и запросы на тягу приветствуются на GitHub по адресу https://github.com/schneems/heapy. Этот проект предназначен для безопасного, гостеприимного пространства для сотрудничества, и ожидается, что участники будут придерживаться Кодекса поведения завета участника.
Драгоценный камень доступен в качестве открытого исходного кода в соответствии с условиями лицензии MIT.