Ruby on rails Arel::Table@Alias在Rails 5中使用时内存泄漏

Ruby on rails Arel::Table@Alias在Rails 5中使用时内存泄漏,ruby-on-rails,ruby,memory-leaks,arel,Ruby On Rails,Ruby,Memory Leaks,Arel,一句话摘要问题:对于使用ActiveRecord进行的每次搜索,是什么导致Arel::Table的@别名数组的大小增加 我使用Rails 5编写了一个简单的web应用程序。当我对它进行负载测试时,内存使用量无限增加。在220万个请求之后,进程的驻留内存大小达到了1GB左右 我通过在执行100000个请求的负载测试之前、之后和10分钟后获取堆转储进行了调查。我使用分析堆转储。它说,大约有39.8万件泄漏的物体是由该公司制造的 这种说法似乎是罪魁祸首: @aliases << node

一句话摘要问题:对于使用ActiveRecord进行的每次搜索,是什么导致
Arel::Table
@别名
数组的大小增加

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

我通过在执行100000个请求的负载测试之前、之后和10分钟后获取堆转储进行了调查。我使用分析堆转储。它说,大约有39.8万件泄漏的物体是由该公司制造的

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

@aliases << node
通过对Arel的修改,我的应用程序的内存使用在负载测试期间保持不变

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

该应用程序有四种型号:

型号

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
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

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

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
# 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)