Bonjour,

Utilisant ZF pour des longs scripts d'intégration de données en base, je rencontre des comportements de "fuites mémoire" avec Zend_Db_Table et Zend_Db_Table_Row.

Le script ci-dessous démontre que la mémoire consommée à l'appel de ces classes n'est jamais libérée :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 
<?php
 
set_include_path(implode(PATH_SEPARATOR, array(
    realpath('D:/Dev/Lib/ZendFramework-1.9.5/library'),
    get_include_path(),
)));
 
require_once('Zend/Registry.php');
require_once('Zend/Db/Adapter/Pdo/Mysql.php');
require_once('Zend/Db/Table.php');
 
$db = new Zend_Db_Adapter_Pdo_Mysql(array(
    'host'     => '127.0.0.1',
    'username' => 'root',
    'password' => 'root',
    'dbname'   => 'dbtest'
    ));
Zend_Db_Table::setDefaultAdapter($db);
 
class test 
{
  private $_table = null;
 
  public function __construct()
  {
    $this->_table = new Zend_Db_Table('account');
  }
 
  public function getRow()
  {
    $select = $this->_table->select()
                           ->from($this->_table->info('name'))
                           ->where("acc_id = ?", '0');
 
    return $this->_table->fetchRow($select);
  }
}
 
# Fonction de test pour N instances de la classe "test"
# et N appels à la méthode getRow()
function run1($i) 
{
  $list = array();
 
  for ($j=0;$j<=$i;$j++) {
    $test = new test();
    $row = $test->getRow();
    $list[] = $test;
  }
}
 
# Fonction de test pour 1 instance de la classe "test"
# et N appels à la méthode getRow()
$test = new test();
 
function run2($i) 
{
  $list = array();
  global $test;
 
  for ($j=0;$j<=$i;$j++) {
    $row = $test->getRow();
    $list[] = $test;
  }
}
 
$start = memory_get_usage(true);
echo "[START] memory : " . round(($start)/1024,2) . " ko<br />";
 
run1(10000);
//run2(10000);
 
$end = memory_get_usage(true);
echo "[END] memory : " . round(($end)/1024,2) . " ko<br />";
 
echo "[DIFF] " . round(($end-$start)/1024,2) . " ko<br />";
 
echo "[PIC] " . round(memory_get_peak_usage(true)/1024,2) . " ko<br />";
Avec run1(1000) soit
1000 instances Zend_Db_Table
1000 instances Zend_Db_Table_Row

[START] memory : 2048 ko
[END] memory : 5632 ko
[DIFF] 3584 ko
[PIC] 16896 ko

Avec run1(10000) soit
10000 instances Zend_Db_Table
10000 instances Zend_Db_Table_Row

[START] memory : 2048 ko
[END] memory : 10752 ko
[DIFF] 8704 ko
[PIC] 151040 ko

Avec run2(1000) soit
1 instances Zend_Db_Table
1000 instances Zend_Db_Table_Row

[START] memory : 2048 ko
[END] memory : 2048 ko
[DIFF] 0 ko
[PIC] 2048 ko

Avec run2(10000) soit
1 instances Zend_Db_Table
10000 instances Zend_Db_Table_Row

[START] memory : 2048 ko
[END] memory : 2560 ko
[DIFF] 512 ko
[PIC] 2816 ko
Avec ces résultats, on remarque le problème se situe surtout au niveau des instances Zend_Db_Table.
Mais surtout la différence de mémoire après l'éxécution de la méthode runX() devraient être égales à 0 car la mémoire consommée doit être libérée. Il y a donc des comportements de fuites mémoires que j'aimerai comprendre.

Quelqu'un aurait t'il une explication et une méthode pour corriger cette fuite ?

Merci par avance.
Kevin