한 문장 요약 질문 : Arel::Table
의 @aliases
배열이 ActiveRecord를 사용하여 검색 할 때마다 크기가 커지면 어떻게 될까요?Arel :: Table @ails 레일스에서 사용할 때 @aliases 메모리 누출
레일즈 5를 사용하여 간단한 웹 응용 프로그램을 작성했습니다.로드를 테스트 할 때 메모리 사용량이 무기한 증가했습니다. 220 만 건의 요청이 있은 후이 프로세스는 최대 1GB의 상주 메모리 크기였습니다.
100,000 요청으로로드 테스트를 실행 한 직후, 직후, 10 분 후에 힙 덤프를 가져와 조사했습니다. 나는 the heap dump diffing tool found here을 사용하여 힙 덤프를 분석했다. Arel::Table#alias()
에 의해 생성 된 약 398,000 개의 유출 된 객체가 있다고합니다.
Arel::Table
의
@aliases
배열
Arel::Table#alias()
내 설치된 버전에
uniq!
에 대한 호출을 추가하여 메모리 누수의 원인을 확인
@aliases << node
:
는이 문은 범인 것 같다
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의 버그인지 아닌지 궁금하거나이 배열을 지우거나 쓰레기를 모으지 않고 자랄 수 있도록 앱에서 나쁜 일을하고있다. Group.dn
및 RadiusDevice.ipv4_address
에 대한 입력 매개 변수를 기반으로 RadiusVsa
에 대한
모델
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
내 유일한 HTTP 엔드 포인트 검색 :
응용 프로그램은 4 가지 모델이있다. 다음은 관련된 ActiveRecord 호출입니다.
# 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)