ruby-on-rails – Rails内存泄漏:控制器类持有对实例的引用

我在Rails 4.2.6应用程序中有内存泄漏.控制器将大型GaragesPresenter对象分配为实例变量,应该在请求完成后对其进行解引用和垃圾回收.但是,我发现这种情况从未发生过.

def show
  @garage = GaragesPresenter.new(@garage,view_context)
  respond_to do |format|
    format.html
  end
end

我看到GaragesController实例正在保存对GaragesPresenter实例的引用,并且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,”方法“:”new“,”generation“:35,”memsize“:56,”flags“:{”wb_protected“:true,”old“:true,”marked“:true}}

GaragesController实例正在对上述对象进行引用(因为show方法将presenter分配为实例变量):

{“address”:“0x7fd0727559f0”,“class”:“0x7fd0727865a0”,“ivars”:22,“references”:[“0x7fd0727558b0”,“0x7fd072755888”,“0x7fd072755838”,“0x7fd0732400e0 “,”0x7fd072754a50“,”0x7fd0734c5658“,”0x7fd07704e878“,”0x7fd0732ab020“,”0x7fd077717ee20“,”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“,”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,”marked“:true}}

解决方法

GaragesPresenter保存对view_context的引用

@garage = GaragesPresenter.new(@garage,view_context)

view_context返回一个instance of of a view class,它保存对self的引用,self是调用控制器:

# File actionview/lib/action_view/rendering.rb,line 71
def view_context
  view_context_class.new(view_renderer,view_assigns,self)
end

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...