2014-06-30 8 views
5

Ich versuche, ein einfaches Programm auszuführen, um Tabellen aus HTML-Code zu extrahieren. Es scheint jedoch ein Speicherproblem mit readHTMLTable im XML-Paket zu geben. Gibt es irgendeine Möglichkeit, dass ich einfach so umgehen könnte? Als würde man irgendwie einen speziellen Speicher für diesen Befehl angeben und ihn dann manuell freigeben.Problemumgehung zu R Speicherverlust mit XML-Paket

Ich habe versucht, dies in eine Funktion zu setzen und versuchte, gc() und verschiedene Versionen von R und dieses Paket und nichts scheint zu funktionieren. Ich fange an verzweifelt zu werden.

Beispielcode. Wie führe ich das aus, ohne die Speichergröße zu explodieren?

library(XML) 
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup") 
while(TRUE) { 
    b = readHTMLTable(a) 
    #do something with b 
} 

Edit: So etwas wie dies noch alle meine Erinnerung nimmt:

library(XML) 
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup") 
f <- function(x) { 
    b = readHTMLTable(x) 
    rm(x) 
    gc() 
    return(b) 
} 

for(i in 1:100) { 
    d = f(a) 
    rm(d) 
    gc() 
} 
rm(list=ls()) 
gc() 

Ich verwende mit 32-Bit und 64-Bit-win 7 und versuchte.

+0

Ich hatte ernsthafte Speicherprobleme mit dem XML-Paket unter Windows. Meine Lösung besteht darin, R regelmäßig neu zu starten (die Daten werden in CSV gespeichert). Ich habe dem Paketautor eine E-Mail geschickt. Wir tauschten einige E-Mails aus, aber er sagte im Grunde, er könne Windows nicht debuggen. – rrs

+0

Ok. Neustarten von R funktioniert, aber es ist nicht so schön, manuelle Arbeit, um alle 5min zu tun. Ich denke, es ist nur ein Weg zu wechseln zu Linux wechseln. XML ist ein sehr cooles Paket, aber leider mit diesen Speicherproblemen zerstört. – Pekka

Antwort

0

Ich hatte auch viele Probleme mit Speicherlecks im XML-Paket (unter Windows und Linux), aber die Art, wie ich es gelöst habe, war, das Objekt am Ende jedes Verarbeitungsschritts zu entfernen, dh ein rm hinzuzufügen (b) und ein gc() am Ende jeder Iteration. Lassen Sie mich wissen, ob dies auch für Sie funktioniert.

+0

Hilft nicht innerhalb der Schleife noch nach der Schleife. – Pekka

+0

Nun, was ich getan habe, war die XML-Verarbeitung in eine Funktion XMLproc setzen, die Ausgabe zurückgegeben, und in der Funktion, wo ich XMLproc aufruft, fügte dann rm (out) und gc() hinzu. Könnten Sie vielleicht nachsehen, ob das für Sie funktioniert? –

+0

Ich habe nichts wie diese Arbeit bekommen. Ich habe etwas hinzugefügt, was ich in der ursprünglichen Frage versucht habe. – Pekka

0

Das gleiche Problem hier, sogar nichts mehr als das Lesen in dem Dokument mit doc <- xmlParse(...); root <- xmlRoot(doc), der Speicher zugewiesen doc wird nur nie freigegeben, um das O/S (wie in Windows Task-Manager überwacht). Eine verrückte Idee, die wir versuchen könnten, ist, system("Rscript ...") zu verwenden, um das XML-Parsing in einer separaten R-Sitzung durchzuführen, wobei das analysierte R-Objekt in einer Datei gespeichert wird, die wir dann in der R-Hauptsitzung einlesen. Hacky, aber es würde zumindest sicherstellen, dass jeder Speicher, der durch das XML-Parsing verschlungen wird, freigegeben wird, wenn die Rscript-Sitzung beendet wird und den Hauptprozess nicht beeinflusst!

+0

Ich löste das, indem ich vor langer Zeit zu Python und BeautifulSoup wechselte :) Wie auch immer, schätze deine Hilfe. Ich werde deine Lösung bald versuchen. – Pekka

+0

Siehe auch die Antwort, die ich auf http://stackoverflow.com/questions/23696391/memory-leak-when-using-package-xml-on-windows/ gestellt habe und die stattdessen die neue xml2-Bibliothek verwendet (ich habe sie als Antwort gepostet) zu dieser Frage auch, aber jemand hat es gelöscht). –

0

Ab XML 3.98-1.4 und R 3.1 auf Win7 kann dieses Problem mit der Funktion free() perfekt gelöst werden. Aber es funktioniert nicht mit readHTMLTable(). Der folgende Code funktioniert einwandfrei.

library(XML) 
a = readLines("http://en.wikipedia.org/wiki/2014_FIFA_World_Cup") 
while(TRUE){ 
    b = xmlParse(paste(a, collapse = "")) 
    #do something with b 
    free(b) 
} 

Das xml2 Paket hat ähnliche Probleme und der Speicher kann mit der Funktion remove_xml() von gc() gefolgt freigegeben werden.