2013-06-17 13 views
8

Wygląda na to, że parsowanie tego samego pliku JSON w kółko w Ruby wykorzystuje coraz większą ilość pamięci. Należy wziąć pod uwagę kod i wyjście poniżej:Dlaczego powtarzające się parsowanie JSON zużywa coraz więcej pamięci?

  1. Dlaczego pamięć nie zwalnia po pierwszej iteracji?
  2. Dlaczego plik JSON 116 MB zajmuje 1,5 GB pamięci RAM po przeanalizowaniu? To zaskakujące, biorąc pod uwagę, że plik tekstowy jest konwertowany na skróty. Czego tu mi brakuje?

Kod:

require 'json' 

def memused 
    `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)[1]/1024 
end 

text = IO.read('../data-grouped/2012-posts.json') 
puts "before parsing: #{memused}MB" 
iter = 1 
while true 
    items = JSON.parse(text) 
    GC.start 
    puts "#{iter}: #{memused}MB" 
    iter += 1 
end 

wyjściowa:

before parsing: 116MB 
1: 1840MB 
2: 2995MB 
3: 2341MB 
4: 3017MB 
5: 2539MB 
6: 3019MB 
+0

śmieci biegnie kolektor gdy chce, co nie ma nic wspólnego z * ty * gdy ma to ... – meagar

+0

Gdyby nie bieg GC, gdy program jest uruchomiony z pamięci? Kiedy json ma 400 MB, używa 5 gigabajtów pamięci na pierwszym iterowaniu i zaczyna później używać swap (co sprawia, że ​​parsowanie trwa dziesiątki minut zamiast sekund). Jak mam przywołać GC, aby wyczyścić tę pamięć? – vrepsys

+0

Które wersje Ruby i JSON są używane? –

Odpowiedz

1

Kiedy Ruby analizuje plik JSON, tworzy wiele pośrednich obiektów, aby osiągnąć cel. Obiekty te pozostają w pamięci, dopóki GC nie zacznie działać.

Jeśli plik JSON ma skomplikowaną strukturę, wiele tablic i wewnętrznych obiektów, liczba wzrośnie zbyt szybko.

Próbowałaś zadzwonić „GC.start” zasugerować Ruby oczyścić nieużywaną pamięć? Jeśli ilość pamięci spadek znaczący, jego sugerują, że jest tylko obiekty pośrednie stosowane do analizowania danych, w przeciwnym razie twoja struktura danych jest skomplikowane albo coś jest dane, że nie można cofnąć przydział lib.

Dla przetwarzania dużych JSON użyć yajl-Ruby (https://github.com/brianmario/yajl-ruby). Jest zaimplementowany w C i ma niewielki rozmiar.

+0

dzięki, zrobię to. To jednak nie odpowiada na moje pytania. – vrepsys

+0

@ user1027996 Edytowałem post i dodałem kilka informacji. –

+0

dodanie GC.start nie robi różnicy – vrepsys