加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-17 03:07:38 所属栏目:百科 来源:网络整理
导读:我在Rails 4.2.6应用程序中有内存泄漏.控制器将大型GaragesPresenter对象分配为实例变量,应该在请求完成后对其进行解引用和垃圾回收.但是,我发现这种情况从未发生过. def show @garage = GaragesPresenter.new(@garage,view_context) respond_to do |format|
我在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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读