跟踪Ruby代码中的内存泄漏

时间:2012-02-21 16:05:22

标签: ruby activerecord memory-leaks

我不是狩猎这些东西的专家,但跟随事情似乎是问题的根源,只是想检查我是否正确,以及如何处理它:

所有脚本基本上都是一个大循环,每次迭代执行以下操作,我认为可能与泄漏有关:

  1. Mechanize对象用于获取远程页面
  2. 调用一个函数来获取或初始化AR对象,但这会发生在具有相同名称的变量
  3. 总是初始化另外两个对象,但相应地使用相同的名称
  4. 我认为,由于新创建的对象被分配给具有相同名称的变量,因此垃圾收集机制应该处理这个......


    更新:我的代码的简化版本

    runner.rb每天都由cronjob运行,它基本上产生了其他脚本的列表 - 蜘蛛:

    ['spider1_path', 'spider2_path', .. ].each do |spider_path|
      Process.detach( fork { exec "ruby #{spider_path}" } )
    end
    


    spider.rb

    # This is the main bit
    #
    agent = Mechanize.new { |agent|
      agent.user_agent_alias = 'Mac Safari'
    }
    
    categories_urls = get_list_of_categories_links_for_website('a')
    categories_urls.each do |category_url|
      next_page = category_url
      while next_page
        doc = fetch_page( next_page, agent )
        cat_page = CategoryPage.new( doc )
        urls_of_sub_pages = cat_page.get_urls_of_sub_pages
    
        urls_of_sub_pages.each do |url|
          page_doc = fetch_page( url, agent )
          sub_page = SubPage.new( page_doc )
          sub_page.parse!
          sub_page.insert
        end
        next_page = cat_page.get_next_page
        # this bit bellow didn't help
        GC.start
      end
    end
    
    ...
    
    def fetch_page( a, url )
      a.get url
    end
    
    ...
    
    class SubPage
      ...
      def parse!
        # @doc - result of `fetch_page`
        @parser = @doc.parser
        # do some scraping using @parser
        # accumulate @attrs hash with necessary information
      end
      ...
    
      def insert
        ad = Ad.where('advert_id = ?', @attrs['advert_id']).first
        if ad
          ad.update_attributes( @attrs )
        else
          ad = Ad.create(@attrs)
        end
      end
    end
    

2 个答案:

答案 0 :(得分:1)

您是否尝试过调用GC.start来偶尔手动触发垃圾回收?我发现在某些情况下,Ruby可以非常懒惰地取出垃圾。

Ruby通常不会“泄漏”内存,但如果你无意中将它们缓存在某个地方,它可能会累积很多已分配的对象。

答案 1 :(得分:0)

您可以尝试使用mem-prof或ruby-prof来分析您的内存使用情况并找出它的使用位置。但是在你真正注意到内存泄漏问题之前我不会打扰。

相关问题