Précédent   Forum des professionnels en informatique > PHP > Langage
Langage Forum sur le langage PHP, la POO, les conventions, la sécurité, etc. Avant de poster : FAQ Langage, toutes les FAQ PHP, cours langage et sources PHP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/03/2011, 16h52   #1
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Par défaut Fuite mémoire

Bonjour,

Le code ci dessous(que vous pouvez tester chez vous) remplit un tableau localement dans une fonction.
A la sortie de la fonction, la mémoire occupée par le tableau n'est pas libérée.

Quelqu'un aurait-il une explication ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
function convert($size)
{
    $unit=array('b','kb','mb','gb','tb','pb');
    return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
 
$start = memory_get_usage(true);
 
function run($i)
{
    $list = array();
    for ($j=0;$j<=$i;$j++) {
        $list[] = '<p>Lorem ipsum dolor sit amet consectetuer id at Nunc tempus justo. Tempor mi Phasellus massa semper pulvinar vitae et interdum ipsum massa. Dui morbi Curabitur a Nullam consectetuer Vestibulum orci consequat id lacus. Phasellus metus ac Sed hendrerit leo wisi pellentesque ipsum lacus auctor. Suspendisse eleifend wisi ut Donec In pede Vestibulum quis tellus orci. Phasellus In semper amet et tellus nibh nibh Vestibulum facilisi.</p>
        <p>Integer volutpat penatibus consequat Integer In mauris Maecenas leo netus sit. Fusce in Aliquam pellentesque congue elit lacus diam amet porttitor tempus. Nunc velit Mauris Vestibulum eget eu mauris ut elit Ut tincidunt. Vivamus tellus condimentum dui adipiscing Aliquam dui justo tempus vitae Proin. Pede dolor a risus Lorem metus condimentum elit at penatibus tellus. </p>
        <p>Vitae congue Duis at felis vitae Ut massa ipsum elit hendrerit. Eu at Sed mauris eu felis et ut hendrerit Curabitur Morbi. Et quis laoreet sagittis convallis Curabitur mauris dignissim vitae et nec. Egestas Aenean elit Curabitur egestas sed velit nibh Donec ligula mauris. Donec cursus cursus amet ante ac.</p>
        <p>Aenean Curabitur wisi Donec ligula Curabitur volutpat fringilla et pede mi. Vestibulum enim semper Sed interdum platea nibh eget montes elit Cras. Libero porttitor volutpat nascetur Aenean metus Sed Lorem vel gravida justo. Donec nunc id urna congue ipsum id justo interdum id convallis. Convallis non penatibus penatibus nunc et eu Donec at consequat Nulla. </p>';            
    }   
 
}   
 
run(10000);
 
$end = memory_get_usage(true);
 
echo "[START] memory : " . convert($start) . "<br />";
echo "[END] memory : " . convert($end) . "<br />";
echo "[DIFF] " . convert($end-$start) . "<br />";
echo "[PEAK] " . convert(memory_get_peak_usage(true)) . "<br />";
Pour ce cas ci, la mémoire fait un bond de 2.75Mo.
Je précise que j'utilise PHP 5.3.5.
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 18h37   #2
Modérateur
 
Avatar de sabotage
 
Homme Vincent
Inscription : juillet 2005
Messages : 14 929
Détails du profil
Informations personnelles :
Nom : Homme Vincent

Informations forums :
Inscription : juillet 2005
Messages : 14 929
Points : 16 381
Points : 16 381
Ton tableau fait 15Mo, il est donc bien liberé.

Tu as par contre 1,75Mo en plus pour la déclaration de tes deux fonctions.
sabotage est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 19h14   #3
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
function convert($size)
{
    $unit=array('b','kb','mb','gb','tb','pb');
    return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
 
function run($i)
{
    $list = array();
    for ($j=0;$j<=$i;$j++) {
        $list[] = '<p>Lorem ipsum dolor sit amet consectetuer id at Nunc tempus justo. Tempor mi Phasellus massa semper pulvinar vitae et interdum ipsum massa. Dui morbi Curabitur a Nullam consectetuer Vestibulum orci consequat id lacus. Phasellus metus ac Sed hendrerit leo wisi pellentesque ipsum lacus auctor. Suspendisse eleifend wisi ut Donec In pede Vestibulum quis tellus orci. Phasellus In semper amet et tellus nibh nibh Vestibulum facilisi.</p>
        <p>Integer volutpat penatibus consequat Integer In mauris Maecenas leo netus sit. Fusce in Aliquam pellentesque congue elit lacus diam amet porttitor tempus. Nunc velit Mauris Vestibulum eget eu mauris ut elit Ut tincidunt. Vivamus tellus condimentum dui adipiscing Aliquam dui justo tempus vitae Proin. Pede dolor a risus Lorem metus condimentum elit at penatibus tellus. </p>
        <p>Vitae congue Duis at felis vitae Ut massa ipsum elit hendrerit. Eu at Sed mauris eu felis et ut hendrerit Curabitur Morbi. Et quis laoreet sagittis convallis Curabitur mauris dignissim vitae et nec. Egestas Aenean elit Curabitur egestas sed velit nibh Donec ligula mauris. Donec cursus cursus amet ante ac.</p>
        <p>Aenean Curabitur wisi Donec ligula Curabitur volutpat fringilla et pede mi. Vestibulum enim semper Sed interdum platea nibh eget montes elit Cras. Libero porttitor volutpat nascetur Aenean metus Sed Lorem vel gravida justo. Donec nunc id urna congue ipsum id justo interdum id convallis. Convallis non penatibus penatibus nunc et eu Donec at consequat Nulla. </p>';            
    }    
}
 
$start = memory_get_usage(true);
 
run(1);
 
$end = memory_get_usage(true);
 
echo "[START] memory : " . convert($start) . "<br />";
echo "[END] memory : " . convert($end) . "<br />";
echo "[DIFF] " . convert($end-$start) . "<br />";
echo "[PEAK] " . convert(memory_get_peak_usage(true)) . "<br />";
J'ai déplacé l'emplacement de $start après le parse des deux fonctions.

La mémoire libérée dépend du nombre d'itérations et non de la déclaration des deux fonctions :

Pour i = 1

Code :
1
2
3
4
[START] memory : 512 kb
[END] memory : 512 kb
[DIFF] 0 b
[PEAK] 512 kb
Pour i = 1000

Code :
1
2
3
4
[START] memory : 512 kb
[END] memory : 2 mb
[DIFF] 1.5 mb
[PEAK] 2 mb
Pour i = 2000

Code :
1
2
3
4
[START] memory : 512 kb
[END] memory : 3 mb
[DIFF] 2.5 mb
[PEAK] 3.5 mb
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 20h44   #4
Modérateur
 
Avatar de sabotage
 
Homme Vincent
Inscription : juillet 2005
Messages : 14 929
Détails du profil
Informations personnelles :
Nom : Homme Vincent

Informations forums :
Inscription : juillet 2005
Messages : 14 929
Points : 16 381
Points : 16 381
Avec PHP5.3 j'obtiens les mêmes résultats que toi.

Cependant, quelque soit le nombre d’itérations on ne dépasse pas 3Mo.
Je pense que l'explication touche à ce qui est décrit ici :
http://bugs.php.net/bug.php?id=33487
sabotage est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 10h05   #5
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Effectivement cela se stabilise vers 3Mo à partir d'un certain seuil. Certainement grâce au garbage collector de php 5.3.

Cependant, mon cas va plus loin. Mon tableau devient une liste d'objet. Avec le code ci dessous, la mémoire ne redescend plus.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function convert($size)
{
    $unit=array('b','kb','mb','gb','tb','pb');
    return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
 
function run($i)
{
    $list = array();
    for ($j=0;$j<=$i;$j++) {
    	$list[] = new stdClass();             
    }   
}
 
$start = memory_get_usage(true);
 
run(1000000);
 
$end = memory_get_usage(true);
 
echo "[START] memory : " . convert($start) . "<br />";
echo "[END] memory : " . convert($end) . "<br />";
echo "[DIFF] " . convert($end-$start) . "<br />";
echo "[PEAK] " . convert(memory_get_peak_usage(true)) . "<br />";
Résultats :

Code :
1
2
3
4
[START] memory : 512 kb
[END] memory : 32.75 mb
[DIFF] 32.25 mb
[PEAK] 220 mb
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 10h38   #6
Modérateur
 
Avatar de sabotage
 
Homme Vincent
Inscription : juillet 2005
Messages : 14 929
Détails du profil
Informations personnelles :
Nom : Homme Vincent

Informations forums :
Inscription : juillet 2005
Messages : 14 929
Points : 16 381
Points : 16 381
Pour moi c'est la même chose et cela correspond toujours à ce que est décrit dans l'article.
sabotage est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 11h26   #7
Membre régulier
 
Inscription : mai 2004
Messages : 121
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 121
Points : 79
Points : 79
Oui c'est vrai. Je trouve curieux que ce "bug" soit toujours présent depuis 2005.

Merci pour ton aide.

Sur ce, je vais clore le sujet.

A bientôt.
hackrobat est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h33.


 
 
 
 
Partenaires

Hébergement Web