2012-05-08 4 views
1

제발 내가 왜이 겉으로보기에 간단한 erb 렌더링 루프의 메모리 크기가 영원히 증가하는지 이해하는 데 도움이됩니다.erb에서 메모리 누수가 발견되었거나 필수적인 것을 놓치고 있습니까? 제발 조언을

는 "alltext.erb는"이런 식으로 뭔가를 보이는 기본 텍스트 파일입니다

는 결국

require 'erb' 

filename = File.expand_path("../alltext.erb", __FILE__) 
file_contents = File.read(filename) 
renderer = ERB.new(file_contents) 

# Undiagnosed memory leak below... 
loop do 

    html = renderer.result(); 

    # Display memory in kb 
    puts `ps -o rss= -p #{Process.pid}`.to_i 

    # Attempt to clear variables and force garbage collection 
    html = nil 
    filename = nil 
    file_contents = nil 
    renderer = nil 
    GC.start 

    # Display memory in kb 
    puts `ps -o rss= -p #{Process.pid}`.to_i 

    sleep(5) 
end 

나는 것 ~ 6백70메가바이트에 모자까지 테스트 케이스 아래 메모리에 성장

<% 5000000.times do %> 
    spam 
<% end %> 

모든 변수를 nil로 설정하고 가비지 콜렉션을 강요하고 범위를 벗어나는 경우 (영원한 루프의 다음 반복으로 진행) 메모리를 확보 할 것으로 기대합니다. 제가 여기서 누락 된 부분을 이해하도록 도와주세요.

내 루비 버전은 1.9.2-p180입니다. OSX를 사용하고 있지만 현재의 우분투 서버에서 관찰 된 동작을 복제하는 것이 테스트 케이스입니다.

+1

하고이를 닫으 결코 : 대신

file_contents = File.read(filename) 

을 : 사용합니다. 작은 스크립트에서는 작동하지만 무한대처럼 만들면 작동하지 않습니다. – ayckoster

+0

이 제안을 반영하도록 코드를 업데이트했지만 메모리 누출에는 영향을 미치지 않습니다. 그래도 감사합니다. –

+0

'renderer = nil'을 제거하지 않고이 작업을 여러 번 반복 실행할 수 없습니다. 그렇게하면 MRI가 실행되지만 1.9.3-p125에서 누출되지 않습니다. –

답변

2

ayckoster가 제안했듯이 "파일을 만들고 절대 닫지 마십시오". 당신은 파일을 생성하는

file_contents = File.new(filename).read 
+0

입력 해 주셔서 감사합니다. 나는이 조정을 무용 노력했다. 나는 또한 파일 선언을 루프에서 빠져 나오려고했다. (이것도 효과가 없다.) 명확히하기 위해 프로세스는 일정 기간 동안 메모리에서 성장한 다음 모자를 쓰는 것처럼 보입니다. 예를 들어 스팸이 5,000,000 번 반복되면이 테스트 루프는 약 670MB로 제한됩니다. 루프간에 객체/참조를 보관하지 않아도 어떻게 이런 일이 발생할 수 있는지 궁금합니다. –