web-dev-qa-db-fra.com

Forcer le garbage collection à s'exécuter dans R avec la commande gc ()

Je programme périodiquement de façon bâclée. D'accord, je programme tout le temps de manière bâclée, mais parfois cela me rattrape sous la forme d'erreurs de mémoire insuffisante. Je commence à exercer un peu de discipline dans la suppression d'objets avec la commande rm() et les choses s'améliorent. Je vois en ligne des messages mitigés sur l'opportunité d'appeler explicitement gc() après avoir supprimé des objets de données volumineux. Certains disent qu'avant que R ne renvoie une erreur de mémoire, il exécutera gc() tandis que d'autres disent que forcer manuellement gc est une bonne idée.

Dois-je exécuter gc() après avoir supprimé des objets volumineux afin de garantir une disponibilité maximale de la mémoire?

64
JD Long

"Probablement." Je le fais aussi, et souvent même en boucle comme dans

cleanMem <- function(n=10) { for (i in 1:n) gc() }

Pourtant, d'après mon expérience, cela ne remet pas la mémoire dans un état vierge.

Donc, ce que je fais habituellement, c'est de garder les tâches à portée de main dans des fichiers de script et d'exécuter celles qui utilisent le frontend "r" (sur Unix et à partir du package "littler"). Rscript est une alternative sur cet autre OS.

Ce flux de travail arrive à être d'accord avec

que nous avons couvert ici avant.

46
Dirk Eddelbuettel

Depuis la page d'aide sur gc :

Un appel de "gc" provoque un ramasse-miettes. Cela se produira également automatiquement sans intervention de l'utilisateur, et le but principal de l'appel de "gc" est pour le rapport sur l'utilisation de la mémoire.

Cependant, il peut être utile d'appeler "gc" après la suppression d'un gros objet, car cela peut inviter R à restituer de la mémoire au système d'exploitation.

Donc cela peut être utile à faire, mais surtout vous ne devriez pas avoir à le faire. Mon opinion personnelle est que c'est le code de dernier recours - vous ne devriez pas joncher votre code avec des instructions gc() comme une évidence, mais si votre machine continue de tomber et que vous avez essayé tout le reste , alors cela pourrait être utile.

Par tout le reste, je veux dire des choses comme

  1. Écrire des fonctions plutôt que des scripts bruts, donc les variables sortent du cadre.

  2. Vider votre espace de travail si vous passez d'un problème à un autre sans rapport.

  3. Jeter les données/variables qui ne vous intéressent pas. (Je reçois fréquemment des feuilles de calcul avec des dizaines de colonnes sans intérêt.)

23
Richie Cotton

Un peu tard pour la fête, mais:

L'appel explicite de gc libérera de la mémoire "maintenant". ... donc si d'autres processus ont besoin de la mémoire, ce pourrait être une bonne idée. Par exemple avant d'appeler system ou similaire. Ou peut-être quand vous aurez "fini" avec le script et que R restera inactif pendant un certain temps jusqu'à ce que le prochain travail arrive - à nouveau, de sorte que d'autres processus obtenir plus de mémoire.

Si vous voulez simplement que votre script s'exécute plus rapidement, cela n'aura pas d'importance car R l'appellera plus tard si nécessaire. Il pourrait même être plus lent car le cycle de GC normal n'aurait peut-être jamais eu besoin de l'appeler.

... mais si vous voulez mesurer le temps par exemple, c'est généralement une bonne idée de faire un GC avant d'exécuter votre test. C'est quoi system.time le fait par défaut.

UPDATE Comme le souligne @DWin, R (ou C #, ou Java etc) ne sait pas toujours quand la mémoire est faible et le GC doit s'exécuter. Vous pourriez donc parfois avoir besoin de faire le GC comme solution de contournement pour les déficiences du système de mémoire.

14
Tommy

Soi-disant R n'utilise que de la RAM. Ce n'est tout simplement pas vrai sur un Mac (et je soupçonne que ce n'est pas vrai sur Windows non plus.) S'il manque de RAM, il commencera à utiliser la mémoire virtuelle. Parfois, mais pas toujours, les processus "reconnaissent" qu'ils doivent exécuter gc () et libérer de la mémoire. Quand ils ne le font pas, vous pouvez le voir en utilisant ActivityMonitor.app et en voyant que tous les RAM sont occupés et l'accès au disque a bondi. Je trouve que lorsque je fais un grand Cox régression s'exécute que je peux éviter de déborder dans la mémoire virtuelle (avec un accès lent au disque) en précédant les appels avec gc(); cph(...)

14
42-

Non. S'il n'y a pas suffisamment de mémoire disponible pour une opération, R exécutera gc() automatiquement.

9
hadley

"Peut être." Je n'ai pas vraiment de réponse définitive. Mais le fichier d'aide suggère qu'il n'y a vraiment que deux raisons d'appeler gc ():

  1. Vous souhaitez un rapport d'utilisation de la mémoire.
  2. Après avoir supprimé un objet volumineux, "il peut être demandé à R de retourner la mémoire au système d'exploitation".

Puisqu'il peut ralentir une grande simulation avec des appels répétés, j'ai tendance à ne le faire qu'après avoir retiré quelque chose de gros. En d'autres termes, je ne pense pas qu'il soit logique de l'appeler systématiquement tout le temps, sauf si vous avez de bonnes raisons de le faire.

7
Shane