2016-06-13 14 views
1

最近、Rubyの大規模なCSVファイルとやりとりする問題が発生しました。明らかな解決策は、このようなファイルの代わりにデータベースにこのデータをホストすることですが、私の問題の根本を見つけたいと思います。Ruby CSVの解析メモリ割り当て

私がやりとりしているデータはあまり大きくありません。約43Mデータポイントです。寸法は8760x5000です。私は実際にこの全体のCSVファイルを読み込む必要があります。そこで、いくつかのマッピング操作を実行してから、新しいファイルにそれをダンプすることができます。

私は両方を試してみた:

CSV.foreach("file") do |row|  
    master_arr << row 
end 

master_arr = CSV.read("file") 

これらのオプションの両方がメモリ割り当てエラーをトリガ - 割り当てられた十分なメモリがない旨。通常、次のようなエラーが表示されます。

C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1798:in `gets': failed to allocate memory (NoMemoryError) 
     from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1798:in `block in shift' 
     from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1796:in `loop' 
     from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1796:in `shift' 
     from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1738:in `each' 
     from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1122:in `block in foreach' 
     from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1273:in `open' 
     from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/csv.rb:1121:in `foreach' 
     from compilation.rb:23:in `<main>' 

これはなぜ問題なのでしょうか。 CSVファイルは約600MBで、私のマシンのリソースを見ると、RAM消費量は、障害が発生する前に約1GBだけ増加します。この間、まだ約10GBの空きRAMがあります。私は、同じサイズの配列を作成し、ランダムなデータを移入した場合

arr1 = Array.new(8760){|i| i+0.111111111111} 
arr2 = Array.new(5000){arr1} 

メモリに格納何ら問題がないものの場合は、CSVファイルに書き込むしようと、私はメモリを受け取ります割り当てエラー。私はCSV.rbファイルを調べましたが、これを引き起こす何かを見つけることができませんでした。

奇妙なことは、これが動作することである:

for i in 0..4999 
    CSV.foreach("file") do |row| 
     master << row 
     break if master_arr.length > 3000 
    end 
end 

が、私は二つにファイルを分割しようとした場合、これは動作しません:

CSV.foreach("file_1_2") do |row|  
    master_arr << row 
end 

CSV.foreach("file_2_2") do |row_1| 
    master_arr << row_1 
end 

それはされていない、これらのオブジェクトのようなものです記憶から解放されましたが、私は何が起こっているのか正確には分かりません。私が言ったように、これは大きなファイルであり、最良の選択肢ではないことは分かっていますが、これは一回限りの解決策であり、問​​題なく使用できるリソースがあります。

+3

64ビットRubyを使用していますか?それは1GBだけだと確信していますか? – tadman

+0

まあ...これはかなり恥ずかしいですが、それは実際問題でした。 Rails用にパッケージ化されたインストーラを使用したときは、32ビットのインスタンスが付属していたと思います。私はこれについても考えなかったとは信じられません。 –

答えて

0

通常、32ビットプログラムは64ビットプログラムよりもはるかに厳しいメモリ制限があり、32ビットRubyは64ビットバージョンと同程度のメモリを割り当てることはできません。

あなたのインストールが正しいバージョンであることを確認でき、そうでない場合は、正しいバージョンに更新してください。 ruby -vは通常、使用しているものを示します。