2016-09-12 5 views
2

한 문장 요약 질문 : 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.dnRadiusDevice.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) 

답변

0

이 메모리 누수는 Arel의 버그입니다. 하루 동안 응답이 없으면 an issue in Rails을 만들었습니다. 이제 수정되었습니다.