Почему в выходных данных кучи ObjectSpace.dump_all в Ruby 2.1 отсутствуют имена и строки файлов?
Недавно я профилировал кучу кода Ruby 2.1.2, используя новый метод ObjectSpace.dump_all. Я получил некоторые полезные данные (используя скрипт, который @tmm1 предлагает в этой ссылке):
931 /app/vendor/bundle/ruby/2.1.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:ARRAY
1015 /app/vendor/bundle/ruby/2.1.0/gems/activemodel-4.1.5/lib/active_model/attribute_methods.rb:385:ARRAY
1015 /app/vendor/bundle/ruby/2.1.0/gems/activemodel-4.1.5/lib/active_model/attribute_methods.rb:385:DATA
1015 /app/vendor/bundle/ruby/2.1.0/gems/activemodel-4.1.5/lib/active_model/attribute_methods.rb:385:NODE
1054 ::REGEXP
1075 ::ICLASS
1095 /app/vendor/ruby-2.1.2/lib/ruby/2.1.0/psych/class_loader.rb:32:STRING
1753 /app/vendor/cache/aws-sdk-core-ruby-99f5012f1162/aws-sdk-core/lib/seahorse/client/net_http/connection_pool.rb:49:ARRAY
1753 /app/vendor/cache/aws-sdk-core-ruby-99f5012f1162/aws-sdk-core/lib/seahorse/client/net_http/connection_pool.rb:49:STRING
1969 /app/vendor/bundle/ruby/2.1.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:NODE
2036 /app/vendor/bundle/ruby/2.1.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:DATA
2507 /app/vendor/bundle/ruby/2.1.0/gems/pg-0.17.1/lib/pg/result.rb:10:STRING
3227 /app/vendor/bundle/ruby/2.1.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:STRING
4592 ::OBJECT
5291 ::CLASS
15623 ::NODE
19227 ::ARRAY
25977 ::DATA
27162 ::HASH
140490 ::STRING
Мой вопрос: почему так много объектов выделяется там, где мы не видим имя файла или номер строки (эти последние шесть строк)? Кажется, что моя проблема связана с большим количеством цепочек, что определенно имеет смысл, учитывая то, что делает это приложение. Но не зная, откуда эти строки строятся, я ничего не могу сделать.
я бегу ObjectSpace.trace_object_allocations_start
когда приложение запускается, задолго до операций я пытаюсь профилировать. И я определенно звоню GC.start
перед каждым вызовом ObjectSpace.dump_all
, Я зову .dump_all
в некотором промежуточном программном обеспечении Sidekiq, которое сбрасывает каждые 100 заданий способом, подобным сообщению @ krasnoukhov.
Я предполагаю, что мой реальный вопрос в том, есть ли здесь кто-то, кто понимает распределение объектов Ruby достаточно, чтобы объяснить, почему ObjectSpace
может не знать происхождение тех STRINGs
?
Спасибо!
Редактировать: я использую в основном тот же код, что и в блоге @ Красноухова
if ENV["PROFILE"]
require "objspace"
ObjectSpace.trace_object_allocations_start
Sidekiq.logger.info "allocations tracing enabled"
module Sidekiq
module Middleware
module Server
class Profiler
# Number of jobs to process before reporting
JOBS = 100
class << self
mattr_accessor :counter
self.counter = 0
def synchronize(&block)
@lock ||= Mutex.new
@lock.synchronize(&block)
end
end
def call(worker_instance, item, queue)
begin
yield
ensure
self.class.synchronize do
self.class.counter += 1
if self.class.counter % JOBS == 0
Sidekiq.logger.info "reporting allocations after #{self.class.counter} jobs"
GC.start
ObjectSpace.dump_all(output: File.open("heap.json", "w"))
Sidekiq.logger.info "heap saved to heap.json"
end
end
end
end
end
end
end
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add Sidekiq::Middleware::Server::Profiler
end
end
end