Ruby on rails Arel::Table@Alias在Rails 5中使用时内存泄漏
一句话摘要问题:对于使用ActiveRecord进行的每次搜索,是什么导致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
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)