2012-05-15 45 views
1

我正在使用Rails 3.1.1並在Heroku上部署。我正在使用open-uri和Nokogiri。Rails:解決Heroku上的內存泄漏問題(也許是Nokogiri)

我想解決一個內存泄漏(?),當我試圖獲取和解析一個XML文件時發生。我提取並試圖解析的XML提要是32 Mb。

我使用下面的代碼是:

require 'open-uri' 
open_uri_fetched = open(feed.fetch_url) 
xml_list = Nokogiri::HTML(open_uri_fetched) 

其中feed.fetch_url是外部XML文件。

看起來,雖然用Nokogiri(我的代碼中的最後一行)解析xml_list,但內存使用率高達540 Mb,並繼續增加。這似乎不合邏輯,因爲XML文件只有32 Mb。

我已經找遍了各種方式來更好地分析這些(例如ruby/ruby on rails memory leak detection),但我無法理解如何使用它們中的任何一種。 MemoryLogic似乎很簡單,但安裝說明似乎缺少一些信息...

所以,請幫我要麼確定上面的代碼是否應該使用多少內存或者如何找到內存泄漏(超級簡單)的說明。

在此先感謝!

回答

2

解析一個大的xml文件並將其轉換爲文檔樹通常會創建一個內存表示,它比xml數據本身大得多。考慮例如

<foo attr="b" /> 

它只有16字節長(假設單字節字符編碼)。這個文檔的內存表示將包含一個表示元素本身的對象,可能是一個(空的)子集合,該元素的集合至少包含一件事物。元素本身具有屬性,如名稱,指向其父文檔的名稱空間指針等。這些東西中的每一個的數據結構可能會超過16個字節,甚至在它們被nokogiri封裝爲ruby對象之前(每個都有一個內存佔用率幾乎肯定大於16字節)。

如果您解析大型xml文件,您幾乎可以肯定地希望使用事件驅動的解析器,如SAX parser,它們在文檔中遇到元素時響應元素,而不是在整個文檔上構建樹表示,然後處理那。

+0

這就是我所做的代碼代碼? Heroku提到我不應該建立一個樹形表示,但我不確定這是否是我實際做的。我加載XML文件並瀏覽每個「產品」元素。 – Christoffer

+0

您正在構建一個樹表示形式(這就是Nokogiri :: HTML所做的),然後遍歷該表示形式。 –

+0

這是一個很好的答案。對於這樣一個大文件,你真的沒有更好的選擇,除非你想使用一些C應用程序。 –

1

你確定你沒有達到heroku允許的「長時間運行任務」的上限嗎?

由於heroku提供給免費贈送的人的一些限制,我已經超時了,並且總是有東西失敗。

我的意思是,你可以在你的開發中複製這個嗎?你的機器需要多長時間來做你想做的事情?

編輯1:

這是怎麼回事?

open_uri_fetched = open(feed.fetch_url) 

它正在提取的URL在哪裏?它在那裏還是在實際上Nokogiri呼叫。無論如何,這個提取需要多長時間?

+0

它可能是這樣的,因爲腳本(如果自由運行)將需要幾個小時。但是,當我收到此錯誤時,在加載Feed時不到一分鐘。在我的開發中,我沒有遇到同樣的問題,但是我沒有相同的錯誤代碼或限制。 – Christoffer

+0

重新編輯:提供的代碼不是完整的代碼,而是相關的部分。 feed.fetch_url是一個字符串,例如「http://domain.com/feed.xml」 – Christoffer