% памяти в скриптах ruby ​​продолжает расти ... любой способ предотвратить это? - PullRequest
0 голосов
/ 27 ноября 2009

, когда я запускаю свой скрипт ruby, который представляет собой очень длинный цикл цикла. для каждого цикла некоторый случайный HTML-файл анализируется с помощью nokogiri.

top показывает, что потребление памяти% увеличивается на 0,1 вместе с использованием процессора каждые несколько секунд.

в итоге скрипт ruby ​​падает из-за "нехватки памяти"

ОБНОВЛЕНО до последней версии:

def extract(newdoc, newarray)
 doc = Nokogiri::HTML(newdoc) 
 collection = ''
 collection = newarray.map {|s| doc.xpath(s)}
 dd = ""; 


(0...collection.first.length).each do |i|
    (0...collection.length).each do |j|
      dd += collection[j][i].to_s
    end
end
 collection = ''
 newarray = ''
 doc = ''
 puts dd.chop + "\n"

end

for 1..100000
extract("somerandomHTMLfile", ["/html/body/p", "/html/body/h1"])
end

Ответы [ 3 ]

1 голос
/ 27 ноября 2009

Исходя из ваших других вопросов, мне интересно, сохраняете ли вы значение extract, или каким-либо другим способом держитесь за ссылку на collection. Я полагаю, вы хотите начать с этого каждый раз?

В любом случае, в других ваших вопросах, кажется, все еще есть некоторые изменения. Вы должны определенно установить все, что вы не хотите сохранять равным нулю между циклами.

Если этого недостаточно, вам может потребоваться выполнить своего рода бинарный поиск по вашей логике и отключить половину вашей программы в сходящемся наборе тестов редактирования, пока не увидите, где происходит потеря памяти.

1 голос
/ 26 ноября 2009

Я не совсем понимаю, как вы перебираете свою коллекцию. Я бы переписал это следующим образом:

collection.each do |coll_of_fields|
  coll_of_fields.each do |field|
    spliceElement(field, dd)
  end
  newrow = dd.chop() + "\n" 
end

Теперь вы, похоже, предполагаете, что в каждом массиве будет как минимум столько же элементов, сколько в первом массиве. Почему бы не зациклить сначала все строки, а затем все элементы подряд?

Также return newrow мне не совсем понятен? Вы останавливаетесь после первой итерации через внешний цикл?

А почему бы вам не использовать /html/body/h1/text() в исходном массиве, в котором вы передаете параметр?

Тогда ваш spliceElement может просто работать со строкой напрямую. Или я что-то упустил?

0 голосов
/ 27 ноября 2009

Вы можете вызывать GC.start после каждого извлечения, чтобы явно запустить сборку мусора и очистить неиспользуемую память.

...