2009-09-03 11 views
3

J'essaie d'éviter la fuite de mémoire en PHP. Lorsque je crée un objet et que je le désactive à la fin, il est toujours en mémoire. Le non apparaît ressemble à:Fuite de mémoire PHP et fork

$obj = NULL; 
unset($obj); 

Encore cela ne va pas aider.

Ma question est ce qui se passera quand je bifurque le processus et l'objet sera créé et détruit dans le fil de l'enfant? Est-ce que ce sera la même chose? Ou y a-t-il une autre façon de libérer la mémoire?

Ceci est le script d'importation qui consommera peu de concerts de RAM.

Répondre

12

PHP 5.3 dispose d'un garbage collector qui peut collecter des références cycliques. Il est peut-être la peine d'essayer:

gc_enable(); 

class A { 
    public function __construct() { 
    $this->data = str_repeat("A", 1024000); 
    } 
} 

$mem = memory_get_usage(); 
$a = new A(); 
$mem2 = memory_get_usage(); 
$a->a = $a; 
$a->a->mydata = $a->data . 'test'; 
$mem3 = memory_get_usage(); 
unset($a); 
gc_collect_cycles(); 
$mem4 = memory_get_usage();  

printf("MEM 1 at start %0.2f Mb\n", ($mem/1024)/1024); 
printf("MEM 2 after first instantiation %0.2f Mb\n", ($mem2/1024)/1024); 
printf("MEM 3 after self-ref: %0.2f Mb\n", ($mem3/1024)/1024); 
printf("MEM 4 after unset(\$a): %0.2f Mb\n", ($mem4/1024)/1024);  

Sortie:

MEM 1 at start: 0.31 Mb 
MEM 2 after first instantiation: 1.29 Mb 
MEM 3 after self-ref: 2.26 Mb 
MEM 4 after unset($a): 0.31 Mb 
+0

+1, bel exemple de données –

5

Pas besoin de définir la variable sur NULL avant d'y appeler unset(). Notez cependant que unset() ne force pas la mémoire à être libérée. La principale chose que vous voudrez peut-être vérifier est que votre objet efface toutes les références a de gros morceaux de données avant que vous ne l'ayez désactivé.

1
bien

votre script d'importation ne devrait pas utiliser quelques concerts de RAM en premier lieu. essayez de stocker les gros morceaux de données à un autre endroit (système de fichiers ou base de données) lorsque vous n'en avez pas absolument besoin. Pensez également à importer des sections plus petites à la fois, pas toutes dans un gros morceau, même si cela prendra plus de temps à traiter, mais de cette façon, vous pourrez échanger la grande consommation de mémoire. Ce dont vous parlez n'est pas une fuite de mémoire, car il s'agit d'un comportement connu et documenté. Comme l'a dit MathieuK, en PHP5.3 vous pouvez utiliser certaines fonctions gc * mais je ne les ai jamais testées. PHP est un très mauvais langage à utiliser pour gérer de gros morceaux de données temporaires, car après une allocation, la mémoire allouée ne sera jamais libérée à nouveau, même si vous l'avez désactivée (parce que la mémoire allouée sera réutilisée, et ceci est une bonne chose dans une page web, mais pas une bonne chose dans un grand script "hardcore" ..).