首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arel::Table @别名在Rails 5中使用时内存泄漏

Arel::Table @别名在Rails 5中使用时内存泄漏
EN

Stack Overflow用户
提问于 2016-09-12 23:53:53
回答 1查看 282关注 0票数 2

一个简单的问题:是什么导致Arel::Table@aliases数组在每次使用ActiveRecord进行的搜索时都会变得越来越大?

我使用Rails 5编写了一个简单的web应用程序,当我加载测试它时,内存使用量无限期地增加。在220万次请求之后,进程的驻留内存大小高达1GB。

我通过在执行负载测试之前、之后、10分钟和10,000次请求之后获得堆转储来进行调查。我使用在这里找到的堆转储扩散工具分析堆转储。它说大约有398,000个由Arel::Table#alias()创建的泄漏对象。

这一说法似乎是罪魁祸首:

代码语言:javascript
复制
@aliases << node

我确认了Arel::Table@aliases数组是内存泄漏的来源,在已安装的Arel::Table#alias()版本中添加了对uniq!的调用。

代码语言:javascript
复制
def alias name = "#{self.name}_2"
  Nodes::TableAlias.new(self, name).tap do |node|
    @aliases << node
  end
  @aliases.uniq! # locally added this line
end

通过对Arel的这一修改,在负载测试期间,我的应用程序的内存使用量保持不变。

据我所知,随着对我的应用程序的每一个请求,@aliases都会增长,并且它会以相同的对象增长。我想知道这是Arel中的一个bug,还是我在我的应用程序中做了一些坏事,导致这个数组在没有被清除或垃圾收集的情况下增长。

该应用程序有四种型号:

模型

代码语言:javascript
复制
class DeviceVendor < ApplicationRecord
end

class Group < ApplicationRecord
end

class RadiusDevice < ApplicationRecord
  belongs_to :device_vendor
  validates :ipv4_address, :ip => {format: :v4}
end

class RadiusVsa < ApplicationRecord
  belongs_to :group
  belongs_to :device_vendor
end

Migrations

代码语言:javascript
复制
class CreateGroups < ActiveRecord::Migration[5.0]
  def change
    create_table :groups do |t|
      t.string :dn
      t.integer :rank

      t.timestamps
    end
  end
end

class CreateDeviceVendors < ActiveRecord::Migration[5.0]
  def change
    create_table :device_vendors do |t|
      t.string :name

      t.timestamps
    end
  end
end

class CreateRadiusDevices < ActiveRecord::Migration[5.0]
  def change
    create_table :radius_devices do |t|
      t.string :ipv4_address
      t.string :model_number
      t.belongs_to :device_vendor, index: true, foreign_key: true

      t.timestamps
    end
  end
end

class CreateRadiusVsas < ActiveRecord::Migration[5.0]
  def change
    create_table :radius_vsas do |t|
      t.string :radius_attributes
      t.belongs_to :device_vendor, index: true, foreign_key: true
      t.belongs_to :group, index: true, foreign_key: true

      t.timestamps
    end

  end
end

我唯一的HTTP端点基于Group.dnRadiusDevice.ipv4_address的输入参数搜索Group.dn。下面是涉及到的ActiveRecord调用:

代码语言:javascript
复制
# groups param value is like: ['ou=foo,cn=bar', 'ou=baz,cn=qux']
group = Group.order(rank: :desc).find_by!(dn: params.require('groups'))
# source param value is like: '10.0.0.1'
radius_device = RadiusDevice.find_by!(ipv4_address: params.require('source'))
# RadiusVsa.find_by! is the call that causes Arel::Table#alias() to be invoked
vendor_attributes = RadiusVsa.find_by!(group: group, device_vendor: radius_device.device_vendor)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-13 18:25:57

事实证明,这个内存泄漏是Arel中的一个bug。在这里一天没有得到响应之后,我们创建了Rails中的问题,现在已经修复了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39460355

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档