Ruby / Mechanize "не удалось выделить память".Стирание экземпляра метода agent.get? - PullRequest
2 голосов
/ 25 августа 2011

У меня небольшая проблема с утечкой памяти в скрипте Mechanize Ruby.

Я "в то время как цикл" несколько веб-страниц обращаются навсегда, и память увеличивается в каждом цикле. Это создало «не удалось выделить память» через несколько минут и завершил работу скрипта.

На самом деле, кажется, что метод agent.get создает экземпляр и хранит результат, даже если я присваиваю результат той же "локальной переменной" или даже "глобальной переменной". Поэтому я попытался присвоить nil переменной после последнего использования и перед повторным использованием переменной с тем же именем. Но похоже, что предыдущие agent.get результаты все еще находятся в памяти и действительно не знают, как истощать ОЗУ, чтобы мой сценарий использовал примерно стабильный объем памяти в нерабочее время?

Вот два кода: (оставайтесь на клавише "ввод" и наблюдайте, как увеличивается объем выделенной памяти в Ruby)

#!/usr/bin/env ruby

require 'mechanize'

agent = Mechanize.new
agent.user_agent_alias = 'Windows Mozilla'
GC.enable
#puts GC.malloc_allocations
while gets.chomp!="stop"
    page = agent.get 'http://www.nypost.com/'
    puts "agent.object_id  : "+agent.object_id.to_s
    puts "page.object_id  : "+page.object_id.to_s
    page=nil
    puts "page.object_id  : "+page.object_id.to_s
    page = agent.get 'http://www.nypost.com/'
    puts "page.object_id  : "+page.object_id.to_s
    page=nil
    puts "page.object_id  : "+page.object_id.to_s
    puts local_variables
    GC.start
    puts local_variables
    #puts GC.malloc_allocations
end

И вместо глобальной переменной:

#!/usr/bin/env ruby

require 'mechanize'

agent = Mechanize.new
agent.user_agent_alias = 'Windows Mozilla'
while gets.chomp!="stop"
    $page = agent.get 'http://www.nypost.com/'
    puts "agent.object_id  : "+agent.object_id.to_s
    puts "$page.object_id  : "+$page.object_id.to_s
    $page = agent.get 'http://www.nypost.com/'
    puts "$page.object_id  : "+$page.object_id.to_s
    #puts local_variables
    #puts global_variables
end

В других языках на переменную влияют повторно, и выделенная память остается стабильной. почему рубин нет? Как я могу заставить экземпляры мусора?

Редактировать: Вот еще один пример использования Object, поскольку Ruby является объектно-ориентированным языком, но результат точно такой же: память снова и снова растет ...

#!/usr/bin/env ruby

require 'mechanize'

$agent = Mechanize.new
$agent.user_agent_alias = 'Windows Mozilla'
class GetContent
    def initialize url
        while true
            @page = $agent.get url
            remove_instance_variable(:@page)
        end
    end
end
myPage = GetContent.new('http://www.nypost.com/')

Мой ответ (недостаточно репутации, чтобы сделать это правильно)

Хорошо, так!

Кажется, что Mechanize::History.clear значительно решает эту проблему утечки памяти.

вот последний измененный код Ruby, если вы хотите проверить до и после ...

#!/usr/bin/env ruby

require 'mechanize'

$agent = Mechanize.new
$agent.user_agent_alias = 'Windows Mozilla'
class GetContent
    def initialize url
        while true
            @page = $agent.get url
            $agent.history.clear
        end
    end
end
myPage = GetContent.new('http://www.nypost.com/')

Ответы [ 2 ]

2 голосов
/ 07 июня 2013

Мое предложение заключается в установке agent.max_history = 0. Как уже упоминалось в списке связанных проблем.

Это предотвратит добавление записи в историю, вместо использования # clear.

Вот модифицированная версия другого ответа

#!/usr/bin/env ruby

require 'mechanize'

$agent = Mechanize.new
$agent.user_agent_alias = 'Windows Mozilla'
$agent.max_history = 0
class GetContent
    def initialize url
        while true
            @page = $agent.get url
        end
    end
end
myPage = GetContent.new('http://www.nypost.com/')
1 голос
/ 15 сентября 2011

Хорошо, так! (имел достаточно репутации, чтобы правильно отвечать на мои вопросы)

Кажется, что Mechanize::History.clear значительно решает эту проблему утечки памяти.

здесьпоследний код Ruby, измененный, если вы хотите проверить до и после ...

#!/usr/bin/env ruby

require 'mechanize'

$agent = Mechanize.new
$agent.user_agent_alias = 'Windows Mozilla'
class GetContent
    def initialize url
        while true
            @page = $agent.get url
            $agent.history.clear
        end
    end
end
myPage = GetContent.new('http://www.nypost.com/')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...