R Speicherverwaltung / Vektor der Größe n Mb kann nicht zugeordnet werden

149

Ich habe Probleme beim Versuch, große Objekte in R zu verwenden. Zum Beispiel:

> memory.limit(4000)
> a = matrix(NA, 1500000, 60)
> a = matrix(NA, 2500000, 60)
> a = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb
> a = matrix(NA, 2500000, 60)
Error: cannot allocate vector of size 572.2 Mb # Can't go smaller anymore
> rm(list=ls(all=TRUE))
> a = matrix(NA, 3500000, 60) # Now it works
> b = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb # But that is all there is room for

Ich verstehe, dass dies mit der Schwierigkeit zusammenhängt, zusammenhängende Speicherblöcke (von hier ) zu erhalten:

Fehlermeldungen, die beginnen, können keinen Größenvektor zuweisen, was darauf hinweist, dass der Speicher nicht abgerufen werden kann, entweder weil die Größe die Adressraumgrenze für einen Prozess überschritten hat oder wahrscheinlicher, weil das System den Speicher nicht bereitstellen konnte. Beachten Sie, dass bei einem 32-Bit-Build möglicherweise genügend freier Speicher verfügbar ist, jedoch nicht genügend zusammenhängender Adressraumblock, um ihn zuzuordnen.

Wie kann ich das umgehen? Meine Hauptschwierigkeit besteht darin, dass ich zu einem bestimmten Punkt in meinem Skript komme und R einem Objekt keine 200-300 MB zuweisen kann ... Ich kann den Block nicht wirklich vorab zuweisen, da ich den Speicher für andere Verarbeitungen benötige. Dies geschieht auch dann, wenn ich nicht benötigte Objekte sorgfältig entferne.

BEARBEITEN: Ja, Entschuldigung: Windows XP SP3, 4 GB RAM, R 2.12.0:

> sessionInfo()
R version 2.12.0 (2010-10-15)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_Caribbean.1252  LC_CTYPE=English_Caribbean.1252   
[3] LC_MONETARY=English_Caribbean.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Caribbean.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
Benjamin
quelle
Versuchen Sie, 'free' zu verwenden, um den Speicher eines anderen nicht verwendeten Prozesses freizugeben.
Manoel Galdino
5
@ Manoel Galdino: Was ist "kostenlos"? Eine R-Funktion?
Benjamin
3
@Manoel: In R wird die Aufgabe zum Freigeben von Speicher vom Garbage Collector und nicht vom Benutzer ausgeführt. Wenn man auf der C-Ebene arbeitet, kann man manuell Callocund Freespeichern, aber ich vermute, das ist nicht das, was Benjamin tut.
Sharpie
In der Bibliothek XML können Sie kostenlos verwenden. Aus der Dokumentation: "Diese generische Funktion steht zur expliziten Freigabe des mit dem angegebenen Objekt verknüpften Speichers zur Verfügung. Sie ist für die Verwendung mit externen Zeigerobjekten vorgesehen, die keine automatische Finalizer-Funktion / -Routine haben, die den von der natives Objekt. "
Manoel Galdino

Antworten:

78

Überlegen Sie, ob Sie all diese Daten wirklich explizit benötigen oder ob die Matrix dünn sein kann? In R gibt es eine gute Unterstützung Matrixfür spärliche Matrizen (siehe Paket für z. B.).

Halten Sie alle anderen Prozesse und Objekte in R auf ein Minimum, wenn Sie Objekte dieser Größe erstellen müssen. Verwenden Sie gc()diese Option , um jetzt nicht verwendeten Speicher zu löschen oder besser nur das benötigte Objekt in einer Sitzung zu erstellen .

Wenn dies nicht helfen kann, besorgen Sie sich einen 64-Bit-Computer mit so viel RAM, wie Sie sich leisten können, und installieren Sie 64-Bit R.

Wenn Sie dies nicht tun können, gibt es viele Onlinedienste für Remote-Computing.

Wenn Sie dies nicht tun können, helfen Ihnen die Speicherzuordnungstools wie package ff(oder bigmemorywie Sascha erwähnt) beim Erstellen einer neuen Lösung. Nach meiner begrenzten Erfahrung ffist das Paket fortgeschrittener, aber Sie sollten das High Performance ComputingThema in CRAN-Aufgabenansichten lesen .

mdsumner
quelle
1
Die Aufgabe ist die Bildklassifizierung mit randomForest. Ich benötige eine Matrix der Trainingsdaten (bis zu 60 Bänder) und 20.000 bis 6.000.000 Zeilen, um sie an randomForest weiterzuleiten. Derzeit kann ich maximal 150.000 Zeilen verwenden, da ich einen zusammenhängenden Block benötige, um das resultierende randomForest-Objekt zu speichern. Aus diesem Grund hilft bigmemory auch nicht, da randomForest ein Matrixobjekt benötigt.
Benjamin
Was meinen Sie mit "nur das Objekt erstellen, das Sie in einer Sitzung benötigen"?
Benjamin
Erstelle 'a' nur einmal, wenn du es beim ersten Mal falsch machst,
starte
1
Ich würde hinzufügen, dass es für Programme, die große Schleifen enthalten, in denen viel berechnet wird, die Ausgabe jedoch relativ klein ist, speichereffizienter sein kann, den inneren Teil der Schleife über Rscript (von einem BASH- oder Python-Skript) aufzurufen. und sortieren / aggregieren Sie die Ergebnisse anschließend in einem anderen Skript. Auf diese Weise wird der Speicher nach jeder Iteration vollständig freigegeben. Durch das erneute Laden / Neuberechnen der an die Schleife übergebenen Variablen wird ein wenig Rechenaufwand verschwendet, aber zumindest können Sie das Speicherproblem umgehen.
Benjamin
54

Für Windows-Benutzer hat mir Folgendes sehr geholfen, einige Speicherbeschränkungen zu verstehen:

  • Öffnen Sie vor dem Öffnen von R den Windows-Ressourcenmonitor (Strg-Alt-Entf / Task-Manager starten / Registerkarte Leistung / Klicken Sie auf die untere Schaltfläche 'Ressourcenmonitor' / Registerkarte Speicher).
  • Sie werden sehen, wie viel RAM-Speicher wir bereits verwendet haben, bevor Sie R öffnen, und von welchen Anwendungen. In meinem Fall werden 1,6 GB der insgesamt 4 GB verwendet. Ich werde also nur 2,4 GB für R bekommen können, aber jetzt kommt es noch schlimmer ...
  • Öffnen Sie R und erstellen Sie einen Datensatz von 1,5 GB. Reduzieren Sie dann die Größe auf 0,5 GB. Der Ressourcenmonitor zeigt an, dass mein RAM zu fast 95% ausgelastet ist.
  • Verwendengc() Sie, um die Speicherbereinigung durchzuführen => es funktioniert, ich kann sehen, dass die Speichernutzung auf 2 GB gesunken ist

Geben Sie hier die Bildbeschreibung ein

Zusätzliche Ratschläge, die auf meinem Computer funktionieren:

  • Bereiten Sie die Features vor, speichern Sie sie als RData-Datei, schließen Sie R, öffnen Sie R erneut und laden Sie die Zug-Features. Der Ressourcenmanager zeigt normalerweise eine geringere Speichernutzung an, was bedeutet, dass selbst gc () nicht den gesamten möglichen Speicher wiederherstellt und das Schließen / erneutes Öffnen von R am besten funktioniert, um mit dem maximal verfügbaren Speicher zu beginnen .
  • Der andere Trick besteht darin, nur den Zugsatz für das Training zu laden (laden Sie nicht den Testsatz, der normalerweise halb so groß wie der Zugsatz sein kann). In der Trainingsphase kann der Speicher maximal genutzt werden (100%), daher ist alles, was verfügbar ist, nützlich. All dies ist mit einem Körnchen Salz zu nehmen, während ich mit R-Speichergrenzen experimentiere.
Timothée HENRY
quelle
9
R sammelt Müll alleine, gc()ist nur eine Illusion. Das Überprüfen des Task-Managers ist nur eine sehr einfache Windows-Operation. Der einzige Rat, dem ich zustimmen kann, ist das Speichern im .RData-Format
David Arenburg
3
@ DavidArenburg gc () ist eine Illusion? Das würde bedeuten, dass das Bild, das ich oben habe, das den Rückgang der Speichernutzung zeigt, eine Illusion ist. Ich denke, Sie liegen falsch, aber ich könnte mich irren.
Timothée HENRY
4
Ich habe nicht gemeint, dass gc()das nicht funktioniert. Ich meine nur, dass R es automatisch macht, so dass Sie es nicht manuell machen müssen. Siehe hier
David Arenburg
2
@DavidArenburg Ich kann Ihnen sicher sagen, dass der Rückgang der Speichernutzung im obigen Bild auf den Befehl gc () zurückzuführen ist. Ich glaube nicht, dass das Dokument, auf das Sie verweisen, korrekt ist, zumindest nicht für mein Setup (Windows, R Version 3.1.0 (10.04.2014) Plattform: i386-w64-mingw32 / i386 (32-Bit)).
Timothée HENRY
15
Ok, zum letzten Mal. gc() Funktioniert . Sie brauchen es einfach nicht zu benutzen, weil R es intern macht
David Arenburg
14

Der einfachste Weg, diese Einschränkung zu umgehen, besteht darin, auf 64-Bit R umzuschalten.

David Heffernan
quelle
25
Das ist im Allgemeinen keine Heilung - ich habe gewechselt und jetzt habe ich Error: cannot allocate vector of size ... Gbstattdessen (aber ja, ich habe viele Daten).
Om-Nom-Nom
2
Vielleicht keine Heilung, aber es hilft viel. Laden Sie einfach RAM auf und starten Sie memory.limit (). Oder denken Sie vielleicht daran, Ihre Daten zu partitionieren / abzutasten.
random_forest_fanatic
Wenn Sie selbst bei 64-Bit-Problemen Probleme haben, die im Wesentlichen unbegrenzt sind, versuchen Sie wahrscheinlich eher, etwas wirklich Massives zuzuweisen. Haben Sie berechnet, wie groß der Vektor theoretisch sein sollte? Andernfalls könnte Ihr Computer mehr RAM benötigen, aber Sie können nur so viel haben.
Hangmanwa7id
Es ist schön, die einfachen Lösungen wie diese vor weiteren Kopf-an-Wand-Lösungen auszuprobieren. Vielen Dank.
Nova
Darüber hinaus ist dies nicht ausschließlich ein Problem mit Windows. Ich verwende derzeit Ubuntu, 64-Bit-R, mit Matrix und habe Schwierigkeiten, ein 20048 x 96448 Matrix-Objekt zu manipulieren.
12

Ich bin auf ein ähnliches Problem gestoßen und habe 2 Flash-Laufwerke als 'ReadyBoost' verwendet. Die beiden Laufwerke haben zusätzlich 8 GB Arbeitsspeicher (für den Cache) bereitgestellt, das Problem gelöst und die Geschwindigkeit des gesamten Systems erhöht. Um Readyboost zu verwenden, klicken Sie mit der rechten Maustaste auf das Laufwerk, gehen Sie zu den Eigenschaften und wählen Sie "ReadyBoost" und das Optionsfeld "Dieses Gerät verwenden". Klicken Sie zum Konfigurieren auf "Anwenden" oder "OK".

Kwaku Damoah
quelle
11

Ich folgte der Hilfeseite von memor.limit und stellte fest, dass R auf meinem Computer standardmäßig bis zu ~ 1,5 GB RAM verwenden kann und dass der Benutzer dieses Limit erhöhen kann. Verwenden Sie den folgenden Code:

>memory.limit()
[1] 1535.875
> memory.limit(size=1800)

hat mir geholfen, mein Problem zu lösen.

Rajib Kumar De
quelle
1
Warum wird dies abgelehnt? Sicher, es ist ein gefährlicher Ansatz, aber es kann oft hilfreich sein, wenn der Sitzung nur ein wenig mehr Speicher zugewiesen werden muss, damit sie funktioniert.
Jeppe Olsen
3
Dies ist nur eine Windows-spezifische Lösung
Jinhua Wang
9

Wenn Sie Ihr Skript unter Linux ausführen, können Sie diesen Befehl verwenden:

bsub -q server_name -R "rusage[mem=requested_memory]" "Rscript script_name.R"

und der Server weist Ihnen den angeforderten Speicher zu (gemäß den Serverlimits, aber bei gutem Server können Riesendateien verwendet werden).

nurit
quelle
1
Kann ich dies auf einer Amazon EC2-Instanz verwenden? Wenn ja, wofür setze ich ein server_name? Ich cannot allocate vector size...stoße darauf, wenn ich versuche, eine riesige Document-Term-Matrix auf einem AMI zu erstellen, und ich kann nicht herausfinden, warum es nicht genug Speicher hat oder wie viel mehr ich mieten muss. Danke dir!
Seth127
Ich bin Ubuntu-Anfänger und benutze Rstudio darauf. Ich habe 16 GB RAM. Wie wende ich den Prozess an, den Sie in der Antwort zeigen? Danke
runjumpfly
3

Die oben erwähnte Save / Load-Methode funktioniert bei mir. Ich bin nicht sicher, wie / ob gc()der Speicher defragmentiert wird, aber dies scheint zu funktionieren.

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
Simon Woodward
quelle