2016-08-04 86 views
0

這是一個解析器,它可以創建一些html頁面並對其進行刮擦,但它會消耗大量內存而不會被垃圾收集。Ruby內存泄漏

這將結果傳遞給表單。這裏會發生內存使用情況。

在這段代碼中是否有明顯的內存泄漏?

def scrape(urls, item_selector) 
    collection = [] 
    urls.each do |url| 
     open(url) do |conn| 
     doc = Nokogiri::HTML(conn.read) # Opens URL 
     @items = doc.css(item_selector)#[0..1] # Sets items 
     @items = @items.map {|item| item['href']} 
     @items.map{|item| Addressable::URI.parse(item).normalize } 
     @items.map{|item| absolute_url(url, item) } 
     @items.each do |item| 
      open(item) do |connect| 
      page = Nokogiri::HTML(connect.read) 
      collection << { 
       :url  => item, 
       :title => get_title(page), 
       :price => get_price(page), 
       :image_url => get_image(page) 
      } 
      end # end connect 
     end # end items 
     end # end conn 
    end #end urls 
    collection 
    end 
+0

根據'item_selector'的值,您可能會將整棵樹放在'@ items'中並將其返回到父範圍。 – Owen

+1

注意:'@items = @ items.map'會創建一個新的對象,並將舊對象保留在內存中。 '@ items.map!'會編輯同一個對象(沒有新對象,沒有拷貝)。 – Myst

+0

請閱讀「[mcve]」。我們不能運行你的代碼,因爲缺少部分,不知道你解析的文件有多大,但是,一般來說,內存泄漏對於處理Nokogiri或Ruby來說並不是問題。在解析時,您似乎在拉動多個頁面,但沒有最小的輸入數據樣本,我們無法確定發生了什麼。 –

回答

0

問題是由於Puma + Ruby> = 2.1.x。固定降級到ruby'2.0.0'。

它不清楚它的內存是否泄漏錯誤或內存膨脹。無論如何,這種組合是內存禁止。

2方式是:

  • 不使用彪馬(使用WEBrick或獨角獸用Ruby 2.3.1沒有這個問題)
  • 降級到2.0.0紅寶石

https://github.com/puma/puma/issues/342

+0

順便說一句,與Nokogiri,Imagemagic,霧寶石沒有任何關係,除了我的代碼是內存密集型的並且一次獲取多個頁面。 –

+1

您正在彙總來自內存中頁面的數據。如果你只做了幾頁,那就是一件事,但如果你在做一個網站或多個網站,那就不是很聰明。使用後備數據庫來存儲您正在捕獲的信息,而不是「集合」。即使是磁盤上的SQLite數據庫也能做到這一點。 Sequel ORM使它很容易使用它。請參閱http://sequel.jeremyevans.net/rdoc/files/README_rdoc.html#label-Getting+Started。 Puma和Unicorn是服務器,所以它們與問題無關,Ruby版本也不是問題。 –

+0

@theTinMan謝謝。你是對的。但是,這個用例需要一個web服務器,所以這是問題,而不是Nokogiri,也不是解析器進程。這是一個錯誤(或問題)呈現任何Web應用程序。我認爲這與刮刮有關,但事實並非如此。 –