У меня есть утечка памяти в приложении Rails 4.2.6. Контроллер выделяет большой объект GaragesPresenter
в качестве переменной экземпляра, который должен быть удален и мусор, собранный после завершения запроса. Однако я вижу, что этого никогда не бывает.Ошибка утечки памяти: класс контроллера, содержащий ссылку на экземпляр
def show
@garage = GaragesPresenter.new(@garage, view_context)
respond_to do |format|
format.html
end
end
Я вижу, что ссылка на экземпляр GaragesPresenter
проводится экземпляром GaragesController
, а экземпляр к тому, что в настоящее время удерживается GaragesController
класса. Это верно уже после того, как запрос завершен и вызывается GC.start
. Почему класс GaragesController
содержит ссылку на экземпляр?
Я знаю это, потому что я создал дамп кучи с:
require 'objspace'
...
GC.start
file = File.open("/tmp/dumpfile", 'w')
ObjectSpace.dump_all(output: file)
И в конечном файле я вижу следующие три объекта:
Следующий объект является GaragesPresenter, который очень большой:
{"address":"0x7fd077217e20", "type":"OBJECT", "class":"0x7fd074a04618", "ivars":7, "references":["0x7fd0772bf940", "0x7fd077711480", "0x7fd077748188", "0x7fd077772898", "0x7fd07720c778", "0x7fd0771ef8d0", "0x7fd0771ef8d0"], "file":"/Users/dyoung/workspace/commutyble/site-app/app/controllers/garages_controller.rb", "line":19, "method":"new", "generation":35, "memsize":56, "flags":{"wb_protected":true, "old":true, "marked":true}}
Ссылки на выше объект проводится экземпляр GaragesController (ожидается, поскольку метод шоу выделяет выступающему в качестве переменного экземпляра):
{"address":"0x7fd0727559f0", "type":"OBJECT", "class":"0x7fd0727865a0", "ivars":22, "references":["0x7fd0727558b0", "0x7fd072755888", "0x7fd072755838", "0x7fd0732400e0", "0x7fd072754a50", "0x7fd0734c5658", "0x7fd07704e878", "0x7fd0732ab020", "0x7fd072785ee8", "0x7fd077217e20", "0x7fd0771ffe10", "0x7fd07720cde0", "0x7fd0732a82d0"], "file":"/Users/dyoung/.rvm/gems/ruby-2.1.0/gems/actionpack-4.2.6/lib/action_controller/metal.rb", "line":237, "method":"new", "generation":35, "memsize":176, "flags":{"wb_protected":true, "old":true, "marked":true}}
Ссылка на экземпляр выше GaragesController в настоящее время проводимый классом GaragesController, предположительно предотвращающий сбор гарабеков. Зачем??
{"address":"0x7fd0727865a0", "type":"CLASS", "class":"0x7fd0726a7260", "name":"GaragesController", "references":["0x7fd0727559f0", "0x7fd0726a72b0"], "file":"/Users/dyoung/.rvm/gems/ruby-2.1.0/gems/activesupport-4.2.6/lib/active_support/callbacks.rb", "line":435, "method":"instance_exec", "generation":35, "memsize":672, "flags":{"wb_protected":true, "old":true, "marked":true}}
Кажется '[WeakRef] (рубин-док. org/stdlib-1.9.3/libdoc/weakref/rdoc/WeakRef.html) 'может помочь – oklas