Warum steigt die Speicherspitzenbelegung, wenn mehr Elemente für die Schleife / Anwendung vorhanden sind?

9

Ich versuche, den Speicherbedarf eines R-Pakets zu reduzieren, und habe ein Verhalten bemerkt, das ich nicht unterdrücken kann. Siehe das folgende Beispiel:

%Vor%

a und b unterscheiden sich nur um ~ 4kb, aber der Garbage Collector meldet eine Differenz von ~ 30mb zwischen der Spitzenspeicherbelegung der Fälle 1 und 2. c benötigt weniger Speicher als sowohl a als auch c , Stelle ich mir nicht ohne eine erhebliche Laufzeitstrafe vor.

Die maximale Speicherzuweisung scheint positiv mit der Anzahl der Spalten zu korrelieren, die beim Aufruf von apply berücksichtigt wurden, aber warum? Führt der Aufruf von apply zu einer Speicherzuordnung, die über den Rahmen einer Iteration hinausgeht? Ich hätte erwartet, dass alle internen Provisorien vor dem Ende jeder Iteration durch gc freigegeben (oder als unbenutzt markiert) werden.

Dieses Verhalten kann reproduziert werden mit lapply über data.frame s und auch mit anderen Funktionen anstelle von quantile .

Ich habe den Eindruck, dass ich einen sehr grundlegenden Aspekt des Speichernutzungsverhaltens in R übersehen habe, aber ich kann mich immer noch nicht darum kümmern. Letztendlich ist meine Frage: Wie kann ich den Speicherbedarf in Fällen wie dem obigen Beispiel weiter reduzieren?

Vielen Dank im Voraus und zögern Sie nicht, auf Ungenauigkeiten in meiner Frage hinzuweisen.

BEARBEITEN:

Gemäß @ ChristopherLoudens Vorschlag habe ich Aufrufe von mem anstelle von gc verwendet und alle drei Fälle wurden als ~ 126.9182mb beschrieben.

%Vor%     
Nicolas De Jay 04.02.2014, 21:19
quelle

1 Antwort

4

Ich denke diesen Satz aus dem Gedächtniskapitel der fortgeschrittenen R-Programmierung von Hadley Wickham am besten fasst den Grund für die Diskrepanz zusammen.

  

Die Garbage-Collection wird normalerweise nur langsam ausgeführt: R ruft gc () auf, wenn mehr Platz benötigt wird. In Wirklichkeit könnte das R den Speicher behalten, nachdem die Funktion beendet wurde, aber es wird es freigeben, sobald es benötigt wird

Das Kapitel hat auch eine gute Funktion namens mem() , mit der Sie besser sehen können, wie viel Speicher ein Codeblock verwendet, als gc() erlaubt. Wenn es die Zeit erlaubt, würde ich den Test mit Wickhams mem() Funktion wiederholen.

Bearbeiten: Wie Peter bemerkte, ist die Funktion mem() veraltet. Verwenden Sie stattdessen die Funktion mem_used() aus dem Paket pryr .

    
Christopher Louden 04.02.2014, 21:29
quelle