Ich habe ein Speicherverlust in einer Rails 4.2.6-Anwendung. Ein Controller weist ein großes GaragesPresenter
-Objekt als Instanzvariable zu, die rückgängig gemacht und nach Abschluss der Anforderung bereinigt werden soll. Ich sehe jedoch, dass dies nie passiert.Rails Speicherverlust: Controller-Klasse, die einen Verweis auf Instanz
def show
@garage = GaragesPresenter.new(@garage, view_context)
respond_to do |format|
format.html
end
end
sehe ich, dass ein Verweis auf die GaragesPresenter
Instanz wird durch die GaragesController
Instanz gehalten wird, und eine Instanz zu dem durch die GaragesController
Klasse festgehalten wird. Dies ist wahr, lange nachdem die Anfrage abgeschlossen und GC.start
aufgerufen wurde. Warum enthält die Klasse GaragesController
einen Verweis auf die Instanz?
Ich weiß das, weil ich einen Heapdump mit ein:
require 'objspace'
...
GC.start
file = File.open("/tmp/dumpfile", 'w')
ObjectSpace.dump_all(output: file)
Und in der resultierenden Datei ich die folgenden drei Objekte sehen:
Das folgende Objekt ist ein GaragesPresenter, das ist sehr groß:
{"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}}
Ein Verweis auf die obige Aufgabe wird durch eine GaragesController Instanz gehalten wird (zu erwarten, da die Show-Methode den Moderator als Instanzvariable zuordnet):
{"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}}
Ein Verweis auf das obigen GaragesController Beispiel wird gehalten von der GaragesController-Klasse, vermutlich verhindert Garabage-Sammlung. Warum??
{"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}}
scheint '[WeakRef] (Rubin-doc. org/stdlib-1.9.3/libdoc/weakref/rdoc/WeakRef.html) 'kann helfen – oklas