#ruby-on-rails #ruby #performance #upload
#ruby-on-rails #ruby #Производительность #загрузка
Вопрос:
Я создал очень большой скрипт, чтобы перенести мои исходные данные в мое приложение Rails. У меня около 3000 строк в моем CSV и 10000 изображений.
После, возможно, 300 загрузок я получил это сообщение :
/usr/local/lib/ruby/gems/1.9.1/gems/activesupport-3.0.9/lib/active_support/core_ext/kernel/agnostics.rb:7:in ``': Cannot allocate memory - identify -format %wx%h '/tmp/stream20111104-14788-1hsumv7.jpg[0]' (Errno::ENOMEM)
Мой скрипт загрузки :
if (row[28] != nil)
hotelalbum = HotelAlbumPhoto.find_or_create_by_title(h.title)
hotelalbum.description = "Album photo de l'hotel " h.title.capitalize
hotelalbum.hotel_id = h.id
hotelalbum.save
files = Dir.glob('IMAGES/' row[28].gsub(/\/,'/') '/*.jpg')
i =0
for file in files
i = 1
photopath = File.expand_path('../../import', __FILE__) '/' file
photoname = file.split('/').last
if (i==1)
hotelalbum.thumbnail = open(photopath)
hotelalbum.save
end
if (i==1)
h.thumbnail = open(photopath)
end
photo = HotelImage.find_or_create_by_image_file_name_and_hotel_album_photo_id(photoname,hotelalbum.id)
if (photo.image_file_size == nil || photo.image_file_name != photoname)
photo.image = open(photopath)
photo.activated = true
photo.alt = "Photo de l'hotel " h.title
photo.save
else
puts photopath ' already updated'
end
end
end
Когда я проверяю свою память с помощью команды top, я вижу, что процесс ruby использует больше памяти при каждой загрузке. Как я могу управлять этим?
Спасибо за помощь
ps: Мой сервер — это виртуальная машина с памятью 512 МБ, одно из решений — увеличить эту память, но я надеюсь найти другое.
Комментарии:
1. Используете ли вы менеджер вложений, такой как paperclip ?
2. В качестве другой точки диагностики, если вы отключите компонент изображения, у него все еще есть проблемы с памятью?
Ответ №1:
Я не знаю, где определена функция open, но я подозреваю, что не вижу соответствующего закрытия…
обновите лучшую идею, измените photo.image = open(photopath)
на photo.image = File.read(photopath)
Согласно документам, прочитайте:
Opens the file, optionally seeks to the given offset, then
returns length bytes (defaulting to the rest of the file).
read ensures the file is closed before returning.
Комментарии:
1. Кажется, нет необходимости закрывать … но вы правы, это странно.
2. без закрытия возможно, что дескриптор файла остается в памяти вместе с содержимым файла…
3. Вы знаете, как я могу закрыть? Спасибо
4. Я даже не знаю, какой open вы вызываете. Обычно это происходит в классе, таком как File.open или подобном. Где определена ваша функция open?
5. Я не знаю, я просто вызываю open в своем скрипте. Это должна быть открытая функция rails по умолчанию 🙂
Ответ №2:
Похоже на проблему с утечкой памяти в ImageMagick? Возможно, это поможет обработать список большими блоками или фрагментами с in_groups_of
и принудительно собирать мусор с GC.start
после каждого фрагмента:
files.in_groups_of(100) {|chunk|
# process chunk
GC.start
}