2014-09-18 6 views
2

필자는 내 Rackspace 클라우드 파일 컨테이너를 통해 반복적으로 다운로드하고 모든 파일의 복사본을 검색하는 스크립트를 작성하여 Rackspace가 유성 및/또는 hindenbugs에 부딪 힐 경우를 대비하여 로컬 백업을 가지고 있습니다.안개 보석 누출 메모리

그러나 내 파일을 다운로드 할 때 내 스크립트가 선형 눈금으로 메모리를 새고있는 것 같습니다. 기본적으로

나는이처럼 보이는 방법이 있습니다

def download_file(fog_file, destination_path) 
    data = fog_file.body 
    File.open(destination_path, 'w') { |f| f.write(data) } 
end 

I 인해 안개의 특성, 내가 메모리에 전체 파일을로드하는 피할 수없는 것을 이해하지만 나는 루비가 메모리를 해제 것이라고 상상 (또는 메모리를 해제 할 수있는 능력이 있어야 함) 각 download_file 호출 후에. 결국 data 변수가 범위를 벗어납니다.

불행히도 시스템 모니터링을 볼 때 메모리 사용량은 스크립트가 충돌 할 때 사용 가능한 메모리를 모두 소모 할 때까지 선형 페이스로 계속 증가합니다.

내가 뭘 잘못하고 있니?

저는 Ubuntu에서 Ruby 2.1.2를 사용하고 있습니다.

+1

누출되는 이유를 잘 모르지만 (fog_file에 대한 참조를 유지합니까?) 안개 파일 다운로드를 스트리밍 할 수 있습니다 (http://www.kylev.com/2013/05/14/foggy-sponges-and- 새끼 고양이/예) –

+0

Ruby는 File.open에 관한 do/end 블록 뒤에 가비지 콜렉션을 내장하고 있습니다. 명시 적으로 파일을 닫고 그 파일이 도움이되는지 확인하십시오. – Anthony

답변

1

두 가지 방법으로 전체 파일을 메모리에로드하지 않아도됩니다.

require 'open-uri' 

file = open(file.public_url).read 
File.open(destination_path, 'w') { |f| f.write(file) } 
:

service = Fog::Storage.new({ provider: 'Rackspace', 
          # ... auth config 
          connection_options: {chunk_size: 102_400} # 100 KB in bytes       
}) 

directory = service.directories.get "dir" 

File.open((destination_path, 'w') do | f | 
    directory.files.get("my_file_on_cloud.png") do | data, remaining, content_length | 
    f.syswrite data 
    end 
end 

둘째, 당신은 파일을 다운로드하여 저장 한 후 OpenUri을 사용하여 안개와 함께 파일의 URL을 검색 할 수 있습니다

첫째, 당신은 척 (이하) 1백킬로바이트에서 파일을 검색 할 수 있습니다

첫 번째 방법은 대상 파일에 직접 쓰고 두 번째 방법은 Tempfile 인스턴스를 만듭니다 (파일 시스템에 임시 파일 만들기). 둘 다 시도해보십시오.

+0

이것은 오래된 질문이며 실제로 첫 번째 방법을 사용하여 문제를 해결했습니다. chunk_size (적어도 Rackspace의 경우)는 메가 바이트가 아닌 바이트를 사용하므로 0.100은 작동하지 않습니다. 나는 한 번에 20 메가 바이트를 얻기 위해'connection_options : {chunk_size : 20_971_520} '을 사용했습니다. 그것은 누출 문제를 해결했습니다. –