Ruby에서 RMagick의 메모리 누출을 처리하는 방법은 무엇입니까?



memory-leaks (3)

나는 Merb와 함께 웹 애플리케이션을 개발하고 있으며 안전하고 안정적인 이미지 처리 라이브러리를 찾고있다. 나는 PHP에서 Imagick과 함께 작업하고, Ruby로 옮겨서 RMagick을 사용하기 시작했다. 그러나 문제가 있습니다. 장기간 실행되는 스크립트로 인해 메모리 누수가 발생합니다. 몇 가지 해결책이 존재하지만 어느 것이 가장 안정적인지는 알 수 없습니다. 그래서 당신은 어떻게 생각하십니까?

지금, 내 애플 리케이션은 PHP에서 이미지를 처리하기 위해 쓴 내부 API를 사용한다. 다른 응용 프로그램과 함께 별도의 서버에서 실행되므로 큰 문제는 아닙니다. 그러나 나는 그것이 좋은 건축이 아니라고 생각한다.

어쨌든, 나는 실용적인 조언을 고려할 것이다.


RMagick을 사용할 때 이미지를 파괴 한 후에 이미지를 파괴해야한다는 것을 기억하는 것이 중요합니다. 그렇지 않으면 큰 이미지 세트로 작업 할 때 / tmp 디렉토리를 채 웁니다. 예를 들어 destroy를 호출해야합니다!

require 'RMagick'

Dir.foreach('/home/tiffs/') do |file|
    next if file == '.' or file == '..'
        image = Magick::Image.read(file).first
        image.format = "PNG"
        image.write("/home/png/#{File.basename(file, '.*')}.png")
        image.destroy!
end

나도이 문제를 만났습니다. 해결책은 가비지 수집을 강제하는 것입니다.

이미지 변수를 새 이미지로 재 할당 한 경우 GC.start를 사용하여 이전 참조가 메모리에서 해제되었는지 확인하십시오.

이후 버전의 RMagick에서는 destroy를 호출 할 수도 있다고 생각합니다! 이미지 처리가 끝나면 이미지에

이 둘의 조합은 아마 당신이 보상받을 수 있도록 보장 할 것이지만, 실제 삶이 성능에 미치는 영향에 대해서는 확신 할 수 없습니다 (나는 대부분의 경우 무시할 만하다).

또는 ImageMagick 명령 줄 클라이언트의 래퍼 인 mini-magick 을 사용할 수도 있습니다.


이것은 ImageMagick 때문이 아닙니다. Ruby 자체 때문일뿐만 아니라 잘 알려진 문제입니다. 내 제안은 프로그램을 두 부분으로 나누는 것입니다. 메모리를 거의 할당하지 않고 시스템 제어 만 처리하는 장기 실행 부분과 실제로 처리 작업을 수행하는 별도의 프로그램입니다. 장기 실행 제어 프로세스는 그것이 생성되는 하위 프로세스에 대한 작업을 찾기에 충분해야하며, 하위 작업은 해당 특정 작업 항목에 대한 모든 처리를 수행해야합니다.

또 다른 옵션은 두 가지를 결합한 상태로 두는 것이지만, 작업 단위가 완료된 후에 exec 을 사용하여 동일한 프로그램의 새로 시작한 버전으로 프로세스를 대체하면 다른 작업 항목을 검색하여 처리하고 다시 exec 할 수 있습니다.

이것은 작업 항목이 상당히 크다고 가정합니다. ImageMagick을 사용하는 경우 거의 확실합니다. 그렇지 않다면 새로운 프로세스를 생성하고 Ruby 인터프리터가 전체 프로그램을 다시 파싱하는 오버 헤드가 너무 커지기 시작한다는 것을 알 수 있습니다. 프로그램을 다시 실행하기 전에 작업 단위 (예 : 10 또는 100)를 처리하도록하면이 문제를 해결할 수 있습니다.





rmagick