ruby - Arel::Table @aliases memory leak when used in Rails 5 -
one sentence summary question: cause arel::table
's @aliases
array grow in size every search done using activerecord?
i have written simple web application using rails 5. when load tested it, memory usage increased indefinitely. after 2.2 million requests, process 1gb of resident memory size.
i investigated getting heap dumps before, right after, , 10 minutes after executing load test 100,000 requests. analyzed heap dumps using the heap dump diffing tool found here. says there 398,000 leaked objects created arel::table#alias()
.
this statement seems culprit:
@aliases << node
i confirmed arel::table
's @aliases
array source of memory leak adding call uniq!
in installed version of arel::table#alias()
:
def alias name = "#{self.name}_2" nodes::tablealias.new(self, name).tap |node| @aliases << node end @aliases.uniq! # locally added line end
with modification arel, app's memory usage remained flat duration of load test.
as far can tell, @aliases
grows every request app, , grows identical objects. wondering whether bug in arel or doing bad in app cause array grow without ever being cleared or garbage collected.
the app has 4 models:
models
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
class creategroups < activerecord::migration[5.0] def change create_table :groups |t| t.string :dn t.integer :rank t.timestamps end end end class createdevicevendors < activerecord::migration[5.0] def change create_table :device_vendors |t| t.string :name t.timestamps end end end class createradiusdevices < activerecord::migration[5.0] def change create_table :radius_devices |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 |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
my http endpoint searches radiusvsa
based on input parameters group.dn
, radiusdevice.ipv4_address
. here activerecord calls involved:
# groups param value like: ['ou=foo,cn=bar', 'ou=baz,cn=qux'] group = group.order(rank: :desc).find_by!(dn: params.require('groups')) # source param value like: '10.0.0.1' radius_device = radiusdevice.find_by!(ipv4_address: params.require('source')) # radiusvsa.find_by! call causes arel::table#alias() invoked vendor_attributes = radiusvsa.find_by!(group: group, device_vendor: radius_device.device_vendor)
it turns out memory leak bug in arel. after getting no responses here day created an issue in rails has been fixed.
Comments
Post a Comment