Попробуйте импортировать строки из CSV в пакетном режиме, например, импортируйте строки в строки DB 1000 за раз, чтобы вы не держались за предыдущие строки, и GC может их собрать.В любом случае это хорошо для базы данных (и для загрузки с s3, если вы передаете CSV
объект ввода-вывода с S3.
s3_io_object = s3_client.get_object(*s3_obj_params).body
csv = CSV.new(s3_io_object, headers: true, header_converters: :symbol)
csv.each_slice(1_000) do |row_batch|
db_model.import ALLOWED_FIELDS, row_batch.map(&:to_h), validate: false
end
Обратите внимание, что я не создаю экземпляры моделей AR длясэкономьте на памяти, и только передавая хэши и сообщая от activerecord-import
до validate: false
.
Кроме того, откуда берется ссылка file
? Кажется, она долгоживущая.
Это не очевидно из вашего примера, но возможно ли, что ссылки на объекты все еще хранятся глобально библиотекой или расширением в вашей среде?
Иногда эти вещи очень трудно отследить, как любой код изВ любом месте, которое вызывается (включая код внешней библиотеки), можно сделать что-то вроде:
Динамическое определение констант, так как они никогда не получат GC'd
Any::Module::Or:Class.const_set('NewConstantName', :foo)
или добавление данных к чему-либо, на что ссылается / владеетконстанта
SomeConstant::Referenceable::Globally.array << foo # array will only get bigger and contents will never be GC'd
В противном случае лучшее, что вы можете сделать, - это использовать некоторые инструменты профилирования памяти, как внутри Ruby (гемы профилирования памяти), так и вне Ruby (работа и система).журналы), чтобы попытаться найти источник.