RubyMotion предполагается сделать автоматическое управление памятью:Как предотвратить утечку памяти в RubyMotion при чтении больших файлов в циклах
RubyMotion обеспечивает автоматическое управление памятью; вам не нужно вернуть неиспользуемые объекты.
, но при чтении больших файлов в цикле я сталкиваюсь с огромными утечками памяти: сотни МБ/с в секунду, точно так же, как если бы мой буфер чтения не был выпущен.
Утечки в основном уходят, если я использую release
в буфере чтения на каждом цикле. Проблема заключается в том, что release
приводит к сбою приложения при завершении цикла.
def readBigBinaryFile(file)
# PURE RUBY WOULD BE
# source=File.open(file,'r')
source =NSFileHandle.fileHandleForReadingAtPath(file)
buffer_size=4096
offset=0
size=File.size(file)
while (offset + buffer_size) <= size
# PURE RUBY WOULD BE
# source.seek(offset)
# abuffer = source.read(buffer_size)
# abuffer=abuffer.to_s
source.seekToFileOffset(offset)
abuffer = source.readDataOfLength(buffer_size)
offset+=buffer_size
@dataPointer ||= Pointer.new(:uchar,4)
abuffer.getBytes(@dataPointer, length: 4)
# memory leaks very rapidly in GBs if we don't release the buffer…
# but this relase action will make the application crash once the doSomething lookp is finished
abuffer.release
end
source.closeFile
return false
end
петля является:
x=0
while x < 10000
my_scan_binary_instance=Scan_binary.new() result=my_scan_binary_instance.readBigBinaryFile(NSBundle.mainBundle.pathForResource("sample1MBfile", ofType:"img"))
puts result.to_s
x+=1
end
puts "if we have used 'abuffer.release', we are going to crash now"
Я проверил реализацию чистого Ruby, и не было утечки памяти на всех, и нет необходимости в вызове высвобождения.
Я нашел «How do I prevent memory leak when I load large pickle files in a for loop?» об утечке памяти в цикле Python, но принято решение делать abuffer=nil
в начале while block
в readBigBinaryFile
не работает.
Это ошибка в автоматическом управлении памятью RubyMotion, или это ожидается? И самое главное, как я могу читать большие файлы в циклах без увеличения использования памяти моего приложения RubyMotion?
Я создал a gist с эффективной реализацией Ruby и a repo примера приложения, воспроизводящего сбой.
Я бы рекомендовал прочитать «[ask]», и особенно ссылку на http://catb.org/esr/faqs/smart-questions.html. «[mcve]» указывает, что ваше примерное приложение должно быть в вопросе _itself_. Ссылки на другие сайты подвержены гниению, а затем ломаются, что делает вопрос бесполезным для других в будущем. –
Внешние ссылки - это товар, сам вопрос, надеюсь, вставляет код, который делает вопрос полным и полезным для других, теперь и позже – MichaelC