Forum Programmation.php fuite mémoire PHP

Posté par  . Licence CC By‑SA.
Étiquettes :
-1
5
mar.
2013

Bonjour,

J'ai une fuite mémoire sur un script PHP, qui me provoque des plantages avec OOM-killer.

Ce script PHP effectue une requête SQL pour récupérer toutes les lignes d'une table PostgreSQL, et génère en RAM un fichier CSV que le navigateur WEB télécharge.

J'ai l'habitude de faire des requêtes PostgreSQL qui me retournent des quantités de données importantes sans avoir de problème de mémoire, donc je pense que c'est la génération du fichier CSV qui pose problème.

Une fois généré le fichier CSV a une taille de 24.2MB (il y'a environ 200000 lignes)

Voici quelques lignes du script :

connect_bdd($connexion_bdd);

$query = SELECT * FROM ma_table

$result = pg_query ($connexion_bdd, $query);

if ($result) 
{
 $nb = pg_num_rows($result);
 echo "# nb = $nb\n\n";
 while ($cells = pg_fetch_row($result))
 {
    echo $cells[0];
    echo ";";
    echo $cells[1];
    echo ";";
    echo $cells[2];
    echo ";";
    echo $cells[3];
    echo ";";
    ...
  }
  pg_free_result($result);
 }
}
else
{
 error_log('ERREUR : Erreur pg_query_params');
 error_log('pg_result_error : Erreur' + pg_result_error($result));
}
disconnect_bdd($connexion_bdd);

Voici la consommation mémoire lorsque je démarre mon serveur apache2 :

top - 10:53:40 up  2:09,  4 users,  load average: 1,19, 1,51, 1,44
Tasks:  88 total,   1 running,  87 sleeping,   0 stopped,   0 zombie
%Cpu(s):  4,8 us,  0,0 sy,  0,0 ni, 95,2 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
KiB Mem:    500780 total,   113632 used,   387148 free,       96 buffers
KiB Swap:        0 total,        0 used,        0 free,    39752 cached

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
 4812 www-data  20   0 23280 4140  552 S   0,0  0,8   0:00.00 apache2
 4813 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2
 4815 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2
 4816 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2
 4817 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2

Une fois le fichier généré et téléchargé par le navigateur, la consommation mémoire est :

top - 10:58:36 up  2:13,  4 users,  load average: 1,74, 1,68, 1,52
Tasks:  90 total,   3 running,  87 sleeping,   0 stopped,   0 zombie
%Cpu(s):  4,8 us,  4,8 sy,  0,0 ni, 90,5 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
KiB Mem:    500780 total,   277236 used,   223544 free,     1456 buffers
KiB Swap:        0 total,        0 used,        0 free,    99672 cached

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
 4812 www-data  20   0  117m 100m 2536 S   0,0 20,6   0:26.72 apache2
 4813 www-data  20   0 23280 4140  552 S   0,0  0,8   0:00.00 apache2
 4815 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2
 4816 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2
 4817 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2
 4825 www-data  20   0 23280 4132  544 S   0,0  0,8   0:00.00 apache2

Donc une fois le script PHP fini, le fichier CSV téléchargé, le processus apache2 de PID 4812 ne libère pas sa mémoire.
Et au bout de quelques fichiers générés apache2 sature la mémoire RAM.

Pourtant je ne vois pas d'erreur dans mon script.

Au niveau configuration du serveur apache2 pour vérifier que ce n'est pas un problème de cache j'ai modifié la configuration de /etc/defaults/apache2 :

## cache size
# HTCACHECLEAN_SIZE=300M
HTCACHECLEAN_SIZE=20M

## interval: if in daemon mode, clean cache every x minutes
# HTCACHECLEAN_DAEMON_INTERVAL=120
HTCACHECLEAN_DAEMON_INTERVAL=1

mais je ne pense pas que ce soit lié.

A noter que je suis sur une plateforme ARM Cortex-A8 DM3730, 512MB de RAM, Debian Wheezy, c'est peut être bug du serveur apache2 dans la nouvelle version de Debian mais ça m'étonnerai.

  • # marrant

    Posté par  . Évalué à 1.

    Quand je vois

    echo $cells[0];
    echo ";";
    echo $cells[1];
    echo ";";
    echo $cells[2];
    echo ";";
    echo $cells[3];
    echo ";";

    j'ai tendance à penser a join, ^ un coup de google php join, et je tombe sur implode
    echo implode(";", $cells);
    ou
    echo join(";", $cells);

    ça ne devrait pas trop t'aider, mais ça rends le code plus concis .

    Ensuite je ne sais pas si c'est du à un mauvais copier/coller, mais le pg_free_result($result); est indenté comme étant dans le while, et les {} n'ont pas l'air équilibré ;)

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: marrant

      Posté par  . Évalué à 1.

      Le code n'est pas complet, je n'ai mis que le code qui peut être utile à comprendre le problème.

      Dans le vrai code, le pg_free_result n'est pas dans la boucle while.

      J'ai fais un test en utilisant la fonction memory_get_usage en début et fin du script PHP, qui mesure la mémoire allouée par le script (http://php.net/manual/en/function.memory-get-usage.php).

      J'obtiens 161984 bytes au début et 165152 bytes à la fin.

      Donc apparement la mémoire RAM consommée par le processus apache ne vient pas de la mémoire allouée par le script PHP..

  • # comme ca, je dirais..

    Posté par  . Évalué à 2.

    … Qu'il te manque un coup de flush.

    tu fais es echos pour écrire ta donnée sur la sortie standard, mais les 24mo reste dans le buffer d'apache tant que tu n'as pas intimé l'ordre à apache de se vider chez le client.

    http://www.php.net/manual/en/function.flush.php

    Il précise dans la doc qu'avec mod_gzip activé sur apache, cet appel de flush restera sans effet.
    Les commentaires sur php.net, comme souvent, sont précieux de détails divers et variés à consulter obligatoirement.

    Autrement, avec le bout de code fournit, je ne vois pas ce qui pourrait bugger. Et n'ayant pas d'expérience de pgsql, je ne saurais connaître ses subtilités.

    Dans ta situation, j’essaierais de virer le bruit de mon script pour le focaliser sur un subset du code suffisamment restreint pour tenter d'identifier l'origine du problème.
    Dans ton exemple je ferais une version qui ne fais que exécuter / boucler - traiter les résultats de requêtes, sans echo, ni sauvegarde en variable.
    Si rien ne se dévoile, alors une autre version avec les echos ect.
    Et ainsi de suite.

    Finalement, étant donné un numéro de version de php (j'imagine qu'étant sous débian tu ne tournes pas sur la toute dernière version) tu pourrais aussi vérifier les changelogs pour voir si un bug ne semble pas te concerner de près ou de loin,
    http://www.php.net/ChangeLog-5.php
    il est assez régulier qu'un ou plusieurs leaks soit corrigés.

    a+

  • # Re: Forum Programmation.php— fuite mémoirePHP

    Posté par  (site web personnel) . Évalué à 1.

    tu peux forcer le passage du garbage collector via gc_collect_cycles()
    http://fr.php.net/manual/fr/function.gc-collect-cycles.php

    et plutôt que de reinventer la roue, tu peux utiliser fputcsv()
    http://fr.php.net/manual/fr/function.fputcsv.php

    • [^] # Re: Forum Programmation.php— fuite mémoirePHP

      Posté par  . Évalué à 1.

      http://php.net/manual/en/features.gc.collecting-cycles.php

      The rationale behind the ability to turn the mechanism on and off, and to initiate cycle collection yourself, is that some parts of your application could be highly time-sensitive. In those cases, you might not want the garbage collection mechanism to kick in. Of course, by turning off the garbage collection for certain parts of your application, you do risk creating memory leaks because some possible roots might not fit into the limited root buffer. Therefore, it is probably wise to call gc_collect_cycles() just before you call gc_disable() to free up the memory that could be lost through possible roots that are already recorded in the root buffer. This then leaves an empty buffer so that there is more space for storing possible roots while the cycle collecting mechanism is turned off.

      Je trouvais ton idée séduisante, mais après lecture de la doc, un peu moins.

  • # ecrire ta sortie dans un fichier CSV

    Posté par  . Évalué à 3.

    autant utiliser le code prevu pour, fputcsv
    qui prend un handle de fichier, un tableau, et genere la ligne de csv qui va bien

    http://lmgtfy.com/?q=php+csv

  • # Script simplifié

    Posté par  . Évalué à 1.

    J'ai simplifié au maximul mon script pour localiser l'erreur :

      /* HEADER TEXT */
      header('Content-Type: text/plain; charset: UTF-8');
      header('Content-Disposition: attachment; filename=test.csv');
    
      error_log('MEM USAGE 1 : '.memory_get_usage());
      (qui donne 149952 bytes)  
    
      for ($i=0; $i<200000; $i++)
      {
       for ($j=0; $j<15; $j++)
       {
        echo rand();
        echo ";";
       }
       echo "\n";
      }
    
      flush();
    
      error_log('MEM USAGE 2 : '.memory_get_usage());
      (qui donne 150072 bytes)
    
    

    Donc là pas de requête PostgreSQL, pas d'allocation en RAM, juste du "echo".

    Le fichier téléchargé fait 30MB

    A chaque fois que je lance la page sur un navigateur WEB et télécharge le fichier généré j'ai un nouveau processus apache2 qui utilise de la mémoire et qui ne termine jamais :

    top -d ,2 -U www-data :

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    3388 www-data 20 0 23384 5880 1728 S 0,0 1,2 0:57.44 apache2
    3389 www-data 20 0 23392 5884 1728 S 0,0 1,2 0:57.03 apache2
    3390 www-data 20 0 23392 5880 1732 S 0,0 1,2 0:29.83 apache2
    3392 www-data 20 0 23352 5840 1732 S 0,0 1,2 0:29.83 apache2
    3393 www-data 20 0 23384 5876 1728 S 0,0 1,2 1:43.94 apache2
    3396 www-data 20 0 23384 5872 1728 S 0,0 1,2 0:53.93 apache2

    Pourquoi ces processus ne se terminent pas ou ne libèrent pas leur mémoire ?

    D'après moi c'est une erreur du serveur apache

    Je testerai demain sur une Debian Squeeze au lieu de Wheezy

    • [^] # Re: Script simplifié

      Posté par  (site web personnel) . Évalué à 2.

      Tu peux aussi essayer Nginx à la place de Apache.

      Il y aussi d'autres serveur web… Cherokee par exemple.

      Pourquoi bloquer la publicité et les traqueurs : https://greboca.com/Pourquoi-bloquer-la-publicite-et-les-traqueurs.html

      • [^] # Re: Script simplifié

        Posté par  . Évalué à 1.

        J'ai testé le même site WEB sur le serveur Nginx, qui semble assez répandu et performant pour des fortes charges avec une consommation mémoire faible.

        Contrairement a apache2, la mémoire est bien libèrée après que le fichier ai été transmis au navigateur WEB :

        Avant execution script PHP :

          PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
         4404 www-data  20   0 20868 5716 2940 S   0,0  1,1   0:07.30 php5-cgi
         4919 www-data  20   0  8256 1316  492 S   0,0  0,3   0:00.00 nginx
        
        

        Pendant execution script PHP :

          PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
         4404 www-data  20   0 70340  53m 2940 R  56,9 10,9   0:14.97 php5-cgi
         4919 www-data  20   0  8256 1636  800 S  21,9  0,3   0:01.44 nginx
        
        

        Après execution script PHP :

          PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
         4404 www-data  20   0 20308 5260 2940 S   0,0  1,1   0:19.01 php5-cgi
         4919 www-data  20   0  8256 1636  800 S   0,0  0,3   0:03.09 nginx
        
        
    • [^] # Re: Script simplifié

      Posté par  . Évalué à 4.

      La directive MaxRequestsPerChild définit combien de requêtes un process apache traite avant qu'il se termine et libère sa mémoire.

      La valeur par défaut, 10000, est bien adaptée pour servir du contenu statique; une valeur beaucoup plus faible est plus adaptée pour du contenu dynamique.

      • [^] # Re: Script simplifié

        Posté par  . Évalué à 0.

        Le problème c'est que en une seule requête PHP le processus apache2 utilise 54MB de mémoire,

        Donc en 10 requête, j'arrive à 100% de mémoire utilisée, ma plateforme ARM en a 512MB.

        Le paramètre MaxMemFree (http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxmemfree) semble plus adapté, je l'ai reglé à 10000 (en KB), mais ça n'a pas résolu le problème.

        Exemple de consommation mémoire après 5 requêtes PHP :

        top - 11:15:22 up  2:15,  4 users,  load average: 1,50, 1,62, 1,64
        Tasks:  93 total,   1 running,  92 sleeping,   0 stopped,   0 zombie
        %Cpu(s):  4,8 us,  0,0 sy,  0,0 ni, 95,2 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
        KiB Mem:    500780 total,   475860 used,    24920 free,     3196 buffers
        KiB Swap:        0 total,        0 used,        0 free,   120628 cached
        
          PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
         5844 www-data  20   0 24360 7204 2556 S   0,0  1,4   0:00.64 apache2
         5845 www-data  20   0 24360 7296 2604 S   0,0  1,5   0:00.62 apache2
         5846 www-data  20   0 24360 6976 2480 S   0,0  1,4   0:00.10 apache2
         5847 www-data  20   0 24360 6976 2480 S   0,0  1,4   0:00.10 apache2
         5848 www-data  20   0 24376 7020 2464 S   0,0  1,4   0:00.16 apache2
         5852 www-data  20   0 72496  54m 2536 S   0,0 11,1   0:20.42 apache2
         5853 www-data  20   0 72496  54m 2536 S   0,0 11,1   0:19.03 apache2
         5858 www-data  20   0 72520  54m 2536 S   0,0 11,2   0:06.34 apache2
         5862 www-data  20   0 72528  54m 2536 S   0,0 11,2   0:08.35 apache2
         5863 www-data  20   0 72496  54m 2536 S   0,0 11,1   0:19.00 apache2
        
        
        • [^] # Re: Script simplifié

          Posté par  (site web personnel) . Évalué à 3.

          Bonjour,

          si avec Nginx la mémoire est libérée à la fin du script, alors tu peux essayer Apache avec le mod-cgi.

          Cela dit, Nginx te fera quand même beaucoup économiser en ressources, CPU et RAM.

          Pourquoi bloquer la publicité et les traqueurs : https://greboca.com/Pourquoi-bloquer-la-publicite-et-les-traqueurs.html

        • [^] # Re: Script simplifié

          Posté par  . Évalué à 5.

          Avec un MaxRequestsPerChild à 1, la mémoire devrait être libérée après chaque requête.

          • [^] # Re: Script simplifié

            Posté par  . Évalué à 1.

            Ok j'ai essayé MaxRequestsPerChild à 1 et ça fonctionne,

            Une fois la requête finie, le processus apache qui a géré la requête se ferme et donc la mémoire est libérée.

            Je trouve ça étonnant que apache même si apache garde ses processus fils ouverts pour être plus réactif, ceux-ci ne libèrent pas leur mémoire automatiquement.

            Cela m'entrainait des erreurs de type OOM :

            [ 8810.445983] postgres invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
            [ 8810.455017] Backtrace:
            [ 8810.457611] [<c00416a8>] (dump_backtrace+0x0/0x110) from [<c03434d0>] (dump_stack+0x18/0x1c)
            [ 8810.466491]  r7:000201da r6:00000000 r5:de5af800 r4:0000006d
            [ 8810.472412] [<c03434b8>] (dump_stack+0x0/0x1c) from [<c00a5454>] (T.356+0x54/0x154)
            [ 8810.480407] [<c00a5400>] (T.356+0x0/0x154) from [<c00a5598>] (T.353+0x44/0x21c)
            [ 8810.488006]  r7:000201da r6:00000000 r5:de5af800 r4:0000006d
            [ 8810.493927] [<c00a5554>] (T.353+0x0/0x21c) from [<c00a59b8>] (out_of_memory+0x248/0x300)
            [ 8810.502380] [<c00a5770>] (out_of_memory+0x0/0x300) from [<c00a8a9c>] (__alloc_pages_nodemask+0x48c/0x57c)
            [ 8810.512359] [<c00a8610>] (__alloc_pages_nodemask+0x0/0x57c) from [<c00aa6bc>] (__do_page_cache_readahead+0xa8/0x1ec)
            [ 8810.523315] [<c00aa614>] (__do_page_cache_readahead+0x0/0x1ec) from [<c00aa828>] (ra_submit+0x28/0x30)
            [ 8810.533020] [<c00aa800>] (ra_submit+0x0/0x30) from [<c00a4250>] (filemap_fault+0x16c/0x3b4)
            [ 8810.541778] [<c00a40e4>] (filemap_fault+0x0/0x3b4) from [<c00b6fc8>] (__do_fault+0x58/0x3d4)
            [ 8810.550598] [<c00b6f70>] (__do_fault+0x0/0x3d4) from [<c00b8100>] (handle_mm_fault+0x304/0x678)
            [ 8810.559661] [<c00b7dfc>] (handle_mm_fault+0x0/0x678) from [<c0044b60>] (do_page_fault+0xe8/0x28c)
            [ 8810.568908] [<c0044a78>] (do_page_fault+0x0/0x28c) from [<c00322a4>] (do_DataAbort+0x3c/0xa0)
            [ 8810.577819] [<c0032268>] (do_DataAbort+0x0/0xa0) from [<c003d5e4>] (ret_from_exception+0x0/0x10)
            [ 8810.586944] Exception stack(0xdd9f9fb0 to 0xdd9f9ff8)
            [ 8810.592224] 9fa0:                                     40b11fd0 00000400 fffff166 40293f38
            [ 8810.600738] 9fc0: befbeedc befbf1fc 00000000 000000c7 befbf51c 403cc10c 00000000 40b12250
            [ 8810.609252] 9fe0: 00000000 befbee78 400f170d 400e1496 00000030 ffffffff
            [ 8810.616149]  r7:000000c7 r6:00000000 r5:befbf1fc r4:ffffffff
            [ 8810.622039] Mem-info:
            [ 8810.624420] Normal per-cpu:
            [ 8810.627319] CPU    0: hi:  186, btch:  31 usd:  31
            [ 8810.632324] active_anon:109444 inactive_anon:661 isolated_anon:0
            [ 8810.632324]  active_file:41 inactive_file:115 isolated_file:0
            [ 8810.632324]  unevictable:10146 dirty:0 writeback:0 unstable:0
            [ 8810.632324]  free:698 slab_reclaimable:592 slab_unreclaimable:1639
            [ 8810.632354]  mapped:8380 shmem:7141 pagetables:998 bounce:0
            [ 8810.662750] Normal free:2792kB min:2844kB low:3552kB high:4264kB active_anon:437776kB inactive_anon:2644kB active_file:164kB inactive_file:460kB unevictable:40584kB isolated(anon):0kB isolated(file):0kB present:505856kB mlocked:40584kB dirty:0kB writeback:0kB mapped:33520kB shmem:28564kB slab_reclaimable:2368kB slab_unreclaimable:6556kB kernel_stack:808kB pagetables:3992kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:953 all_unreclaimable? yes
            [ 8810.704620] lowmem_reserve[]: 0 0
            [ 8810.708068] Normal: 650*4kB 14*8kB 3*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 2792kB
            [ 8810.718994] 8755 total pagecache pages
            [ 8810.722900] 0 pages in swap cache
            [ 8810.726348] Swap cache stats: add 0, delete 0, find 0/0
            [ 8810.731781] Free swap  = 0kB
            [ 8810.734771] Total swap = 0kB
            [ 8810.751281] 131072 pages of RAM
            [ 8810.754547] 986 free pages
            [ 8810.757385] 5877 reserved pages
            [ 8810.760650] 2231 slab pages
            [ 8810.763549] 78479 pages shared
            [ 8810.766723] 0 pages swap cached
            [ 8810.769989] [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
            [ 8810.777709] [ 1566]     0  1566      572      214   0     -17         -1000 udevd
            [ 8810.785522] [ 2960]     0  2960     6876      273   0       0             0 rsyslogd
            [ 8810.793609] [ 3011]   103  3011     1069      159   0       0             0 dnsmasq
            [ 8810.801635] [ 3124]     0  3124      846      175   0       0             0 cron
            [ 8810.809356] [ 3161]   104  3161    11130     1527   0     -13          -900 postgres
            [ 8810.817443] [ 3169]   104  3169    11130     2385   0       0             0 postgres
            [ 8810.825531] [ 3170]   104  3170    11130      499   0       0             0 postgres
            [ 8810.833587] [ 3171]   104  3171    11130      452   0       0             0 postgres
            [ 8810.841644] [ 3172]   104  3172     3640      304   0       0             0 postgres
            [ 8810.849731] [ 3188]     0  3188     1521      216   0     -17         -1000 sshd
            [ 8810.857452] [ 3240]     0  3240      416      144   0       0             0 getty
            [ 8810.865234] [ 3242]     0  3242     2277      539   0       0             0 sshd
            [ 8810.872955] [ 3246]     0  3246      667      178   0       0             0 sftp-server
            [ 8810.881286] [ 3247]     0  3247     2277      540   0       0             0 sshd
            [ 8810.888977] [ 3255]     0  3255     1045      235   0       0             0 bash
            [ 8810.896697] [ 3269]     0  3269     2277      540   0       0             0 sshd
            [ 8810.904418] [ 3279]     0  3279     1085      243   0       0             0 bash
            [ 8810.912109] [ 3646]     0  3646     2277      540   0       0             0 sshd
            [ 8810.919830] [ 3658]     0  3658     1063      253   0       0             0 bash
            [ 8810.927551] [ 4568]     0  4568    10336    10146   0       0             0 acquisition
            [ 8810.935882] [ 4569]   104  4569    11451     1083   0       0             0 postgres
            [ 8810.943939] [ 4575]   104  4575    11451     1423   0       0             0 postgres
            [ 8810.952026] [ 4576]   104  4576    11195     2383   0       0             0 postgres
            [ 8810.960083] [ 4695]     0  4695     2277      540   0       0             0 sshd
            [ 8810.967803] [ 4709]     0  4709     1047      237   0       0             0 bash
            [ 8810.975494] [ 4839]     0  4839     1048      237   0       0             0 top
            [ 8810.983123] [ 5458]     0  5458     2277      540   0       0             0 sshd
            [ 8810.990844] [ 5466]     0  5466      700      184   0       0             0 sftp-server
            [ 8810.999176] [ 5825]     0  5825     5814     1236   0       0             0 apache2
            [ 8811.007141] [ 5844]    33  5844     6090     1487   0       0             0 apache2
            [ 8811.015136] [ 5845]    33  5845    12236     7625   0       0             0 apache2
            [ 8811.023101] [ 5846]    33  5846    12244     7598   0       0             0 apache2
            [ 8811.031097] [ 5847]    33  5847     8906     4222   0       0             0 apache2
            [ 8811.039062] [ 5848]    33  5848    18130    13666   0       0             0 apache2
            [ 8811.047058] [ 5849]   104  5849    11642     1548   0       0             0 postgres
            [ 8811.055145] [ 5851]   104  5851    11898     5538   0       0             0 postgres
            [ 8811.063232] [ 5852]    33  5852    18124    13645   0       0             0 apache2
            [ 8811.071197] [ 5853]    33  5853    18124    13648   0       0             0 apache2
            [ 8811.079193] [ 5858]    33  5858    18130    13651   0       0             0 apache2
            [ 8811.087158] [ 5859]   104  5859    11804     5511   0       0             0 postgres
            [ 8811.095275] [ 5860]   104  5860    11642     5287   0       0             0 postgres
            [ 8811.103363] [ 5861]   104  5861    11642     6979   0       0             0 postgres
            [ 8811.111419] [ 5862]    33  5862    18132    13652   0       0             0 apache2
            [ 8811.119415] [ 5863]    33  5863    18124    13645   0       0             0 apache2
            [ 8811.127380] [ 5870]   104  5870    11642     6728   0       0             0 postgres
            [ 8811.135437] [ 5900]   104  5900    11642     6921   0       0             0 postgres
            [ 8811.143524] [ 5994]   104  5994    11642     6925   0       0             0 postgres
            [ 8811.151580] [ 6674]   104  6674    11642     6972   0       0             0 postgres
            [ 8811.159667] [ 6689]   104  6689    11642     6918   0       0             0 postgres
            [ 8811.167724] [ 6753]     0  6753     1552      373   0       0             0 vim
            [ 8811.175354] Out of memory: Kill process 5848 (apache2) score 109 or sacrifice child
            [ 8811.183319] Killed process 5848 (apache2) total-vm:72520kB, anon-rss:53380kB, file-rss:1284kB
            [ 8967.585662] top invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
            [ 8967.594299] Backtrace:
            [ 8967.596893] [<c00416a8>] (dump_backtrace+0x0/0x110) from [<c03434d0>] (dump_stack+0x18/0x1c)
            [ 8967.605682]  r7:000201da r6:00000000 r5:dda30880 r4:0000008d
            [ 8967.611602] [<c03434b8>] (dump_stack+0x0/0x1c) from [<c00a5454>] (T.356+0x54/0x154)
            [ 8967.619598] [<c00a5400>] (T.356+0x0/0x154) from [<c00a5598>] (T.353+0x44/0x21c)
            [ 8967.627197]  r7:000201da r6:00000000 r5:dda30880 r4:0000008d
            [ 8967.633117] [<c00a5554>] (T.353+0x0/0x21c) from [<c00a59b8>] (out_of_memory+0x248/0x300)
            [ 8967.641571] [<c00a5770>] (out_of_memory+0x0/0x300) from [<c00a8a9c>] (__alloc_pages_nodemask+0x48c/0x57c)
            [ 8967.651519] [<c00a8610>] (__alloc_pages_nodemask+0x0/0x57c) from [<c00aa6bc>] (__do_page_cache_readahead+0xa8/0x1ec)
            [ 8967.662506] [<c00aa614>] (__do_page_cache_readahead+0x0/0x1ec) from [<c00aa828>] (ra_submit+0x28/0x30)
            [ 8967.672210] [<c00aa800>] (ra_submit+0x0/0x30) from [<c00a4250>] (filemap_fault+0x16c/0x3b4)
            [ 8967.680908] [<c00a40e4>] (filemap_fault+0x0/0x3b4) from [<c00b6fc8>] (__do_fault+0x58/0x3d4)
            [ 8967.689697] [<c00b6f70>] (__do_fault+0x0/0x3d4) from [<c00b8100>] (handle_mm_fault+0x304/0x678)
            [ 8967.698760] [<c00b7dfc>] (handle_mm_fault+0x0/0x678) from [<c0044b60>] (do_page_fault+0xe8/0x28c)
            [ 8967.708038] [<c0044a78>] (do_page_fault+0x0/0x28c) from [<c0032204>] (do_PrefetchAbort+0x3c/0xa0)
            [ 8967.717285] [<c00321c8>] (do_PrefetchAbort+0x0/0xa0) from [<c003d5e4>] (ret_from_exception+0x0/0x10)
            [ 8967.726806] Exception stack(0xde683fb0 to 0xde683ff8)
            [ 8967.732055] 3fa0:                                     000434c8 00920000 40299365 40118008
            [ 8967.740570] 3fc0: 0001fd80 00000000 bed689b4 0001e7dc 0001d628 0001d1a0 0001db90 0001d1a0
            [ 8967.749084] 3fe0: 4039c290 bed67ee0 0000e17f 0000e17e 20000030 ffffffff
            [ 8967.755981]  r7:0001e7dc r6:bed689b4 r5:00000000 r4:ffffffff
            [ 8967.761871] Mem-info:
            [ 8967.764251] Normal per-cpu:
            [ 8967.767150] CPU    0: hi:  186, btch:  31 usd:  46
            [ 8967.772155] active_anon:109550 inactive_anon:657 isolated_anon:0
            [ 8967.772155]  active_file:60 inactive_file:108 isolated_file:0
            [ 8967.772155]  unevictable:10146 dirty:0 writeback:0 unstable:0
            [ 8967.772186]  free:683 slab_reclaimable:584 slab_unreclaimable:1632
            [ 8967.772186]  mapped:8464 shmem:7141 pagetables:954 bounce:0
            [ 8967.802612] Normal free:2732kB min:2844kB low:3552kB high:4264kB active_anon:438200kB inactive_anon:2628kB active_file:240kB inactive_file:432kB unevictable:40584kB isolated(anon):0kB isolated(file):0kB present:505856kB mlocked:40584kB dirty:0kB writeback:0kB mapped:33856kB shmem:28564kB slab_reclaimable:2336kB slab_unreclaimable:6528kB kernel_stack:792kB pagetables:3816kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:1018 all_unreclaimable? yes
            [ 8967.844573] lowmem_reserve[]: 0 0
            [ 8967.848022] Normal: 553*4kB 57*8kB 2*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 2732kB
            [ 8967.858947] 8767 total pagecache pages
            [ 8967.862823] 0 pages in swap cache
            [ 8967.866302] Swap cache stats: add 0, delete 0, find 0/0
            [ 8967.871734] Free swap  = 0kB
            [ 8967.874725] Total swap = 0kB
            [ 8967.891204] 131072 pages of RAM
            [ 8967.894500] 978 free pages
            [ 8967.897338] 5877 reserved pages
            [ 8967.900604] 2216 slab pages
            [ 8967.903503] 72890 pages shared
            [ 8967.906677] 0 pages swap cached
            [ 8967.909942] [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
            [ 8967.917694] [ 1566]     0  1566      572      214   0     -17         -1000 udevd
            [ 8967.925476] [ 2960]     0  2960     6876      275   0       0             0 rsyslogd
            [ 8967.933563] [ 3011]   103  3011     1069      159   0       0             0 dnsmasq
            [ 8967.941528] [ 3124]     0  3124      846      175   0       0             0 cron
            [ 8967.949249] [ 3161]   104  3161    11130     1527   0     -13          -900 postgres
            [ 8967.957305] [ 3169]   104  3169    11130     2384   0       0             0 postgres
            [ 8967.965393] [ 3170]   104  3170    11130      499   0       0             0 postgres
            [ 8967.973449] [ 3171]   104  3171    11130      460   0       0             0 postgres
            [ 8967.981536] [ 3172]   104  3172     3640      304   0       0             0 postgres
            [ 8967.989593] [ 3188]     0  3188     1521      216   0     -17         -1000 sshd
            [ 8967.997314] [ 3240]     0  3240      416      144   0       0             0 getty
            [ 8968.005096] [ 3242]     0  3242     2277      539   0       0             0 sshd
            [ 8968.012817] [ 3246]     0  3246      667      178   0       0             0 sftp-server
            [ 8968.021148] [ 3247]     0  3247     2277      540   0       0             0 sshd
            [ 8968.028869] [ 3255]     0  3255     1045      235   0       0             0 bash
            [ 8968.036560] [ 3269]     0  3269     2277      540   0       0             0 sshd
            [ 8968.044342] [ 3279]     0  3279     1085      243   0       0             0 bash
            [ 8968.052062] [ 3646]     0  3646     2277      540   0       0             0 sshd
            [ 8968.059783] [ 3658]     0  3658     1063      253   0       0             0 bash
            [ 8968.067474] [ 4568]     0  4568    10336    10146   0       0             0 acquisition
            [ 8968.075836] [ 4569]   104  4569    11451     1076   0       0             0 postgres
            [ 8968.083892] [ 4575]   104  4575    11451     1498   0       0             0 postgres
            [ 8968.091979] [ 4576]   104  4576    11195     2428   0       0             0 postgres
            [ 8968.100036] [ 4695]     0  4695     2277      540   0       0             0 sshd
            [ 8968.107727] [ 4709]     0  4709     1048      238   0       0             0 bash
            [ 8968.115447] [ 4839]     0  4839     1048      241   0       0             0 top
            [ 8968.123077] [ 5458]     0  5458     2277      540   0       0             0 sshd
            [ 8968.130767] [ 5466]     0  5466      700      184   0       0             0 sftp-server
            [ 8968.139129] [ 5825]     0  5825     5814     1236   0       0             0 apache2
            [ 8968.147094] [ 5844]    33  5844     6090     1487   0       0             0 apache2
            [ 8968.155090] [ 5845]    33  5845    12236     7625   0       0             0 apache2
            [ 8968.163055] [ 5846]    33  5846    22485    17722   0       0             0 apache2
            [ 8968.171051] [ 5847]    33  5847    12242     7597   0       0             0 apache2
            [ 8968.179016] [ 5849]   104  5849    11642     1543   0       0             0 postgres
            [ 8968.187103] [ 5851]   104  5851    11898     5525   0       0             0 postgres
            [ 8968.195159] [ 5852]    33  5852    18124    13645   0       0             0 apache2
            [ 8968.203155] [ 5853]    33  5853    18124    13648   0       0             0 apache2
            [ 8968.211120] [ 5858]    33  5858    18130    13651   0       0             0 apache2
            [ 8968.219146] [ 5859]   104  5859    11642     5376   0       0             0 postgres
            [ 8968.227233] [ 5860]   104  5860    11771     7303   0       0             0 postgres
            [ 8968.235290] [ 5862]    33  5862    18132    13652   0       0             0 apache2
            [ 8968.243286] [ 5863]    33  5863    18124    13645   0       0             0 apache2
            [ 8968.251251] [ 5870]   104  5870    11642     6719   0       0             0 postgres
            [ 8968.259338] [ 5900]   104  5900    11642     6907   0       0             0 postgres
            [ 8968.267395] [ 5994]   104  5994    11642     6915   0       0             0 postgres
            [ 8968.275482] [ 6674]   104  6674    11642     6960   0       0             0 postgres
            [ 8968.283538] [ 6689]   104  6689    11642     6904   0       0             0 postgres
            [ 8968.291595] [ 6773]     0  6773      748      102   0       0             0 tail
            [ 8968.299316] Out of memory: Kill process 5846 (apache2) score 141 or sacrifice child
            [ 8968.307281] Killed process 5846 (apache2) total-vm:89940kB, anon-rss:69604kB, file-rss:1284kB
            
            

            Merci pour ton aide

            • [^] # Re: Script simplifié

              Posté par  . Évalué à 2.

              Je suis content de voir que tu as trouvé une solution à ton problème mais j'ai une question (de béotien) sur une de tes remarques.

              Je trouve ça étonnant que apache même si apache garde ses processus fils ouverts pour être plus réactif, ceux-ci ne libèrent pas leur mémoire automatiquement.

              Garder les processus fils pour être réactif n'est-il pas incompatible avec une libération de la mémoire ? Je veux dire, si on libère la mémoire il faut recharger (en mémoire), alors il n'y aurait plus aucun gain de performance ?

              • [^] # Re: Script simplifié

                Posté par  . Évalué à -1.

                je veux bien qu il garde des choses en mémoire, mais là garder le resultat d une requete sql qui fait 50MB, où est la limite ?
                je crois vraiment qu il s agit d un bug
                ou alors ce sont des buffers de communication entre postgresql et php ou entre php et apache qui ne sont pas libérés

    • [^] # Re: Script simplifié

      Posté par  . Évalué à 1. Dernière modification le 06 mars 2013 à 11:48.

      hello,

      j'ai copié coller ton script sur mon apache local ici.

      uname -a
      Linux clement-PC 3.5.0-26-generic #40-Ubuntu SMP Tue Feb 26 19:59:36 UTC 2013 i686 i686 i686 GNU/Linux
      
      PHP/5.4.6-1ubuntu1.1
      
      

      un ps avant
      un ps après le premier dl
      un ps après plusieurs dl (10aine)

      clement@clement-PC:~$ ps aux | grep apa
      USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
      root     13051  0.0  0.3  73916 12680 ?        Ss   18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13058  0.0  0.1  74204  5532 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13059  0.0  0.1  74188  5392 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13060  0.0  0.1  73980  5112 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13061  0.0  0.1  73948  4408 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13062  0.0  0.1  73948  4408 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 14824  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      www-data 14825  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      www-data 14826  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      clement  15248  0.0  0.0   4448   868 pts/2    S+   18:32   0:00 grep --color=auto apa
      clement@clement-PC:~$ ps aux | grep apa
      root     13051  0.0  0.3  73916 12680 ?        Ss   18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13058  0.0  0.1  74204  5532 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13059  0.0  0.1  74188  5392 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13060  0.0  0.1  73980  5112 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13061  6.0  0.1  74244  6696 ?        S    18:31   0:06 /usr/sbin/apache2 -k start
      www-data 13062  0.0  0.1  73948  4408 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 14824  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      www-data 14825  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      www-data 14826  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      clement  15557  0.0  0.0   4448   868 pts/2    S+   18:33   0:00 grep --color=auto apa
      clement@clement-PC:~$ ps aux | grep apa
      root     13051  0.0  0.3  73916 12680 ?        Ss   18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13058  0.0  0.1  74204  5532 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13059  0.0  0.1  74188  5392 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13060  0.0  0.1  73980  5112 ?        S    18:31   0:00 /usr/sbin/apache2 -k start
      www-data 13061  3.3  0.1  74244  6696 ?        S    18:31   0:06 /usr/sbin/apache2 -k start
      www-data 13062 20.9  0.1  74252  6464 ?        S    18:31   0:40 /usr/sbin/apache2 -k start
      www-data 14824 17.2  0.1  74252  6464 ?        S    18:32   0:20 /usr/sbin/apache2 -k start
      www-data 14825  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      www-data 14826  0.0  0.1  73948  4408 ?        S    18:32   0:00 /usr/sbin/apache2 -k start
      clement  16698  0.0  0.0   4448   868 pts/2    S+   18:34   0:00 grep --color=auto apa
      clement@clement-PC:~$ 
      
      

      Donc effectivement pas le même constat en fin de compte.

      a+

      • [^] # Re: Script simplifié

        Posté par  . Évalué à 1.

        Bonjour,

        C'est lorsque je rajoute la requête SQL que la mémoire utilisée passe à ~50MB.

        Pourtant il n'y a pas de fuite mémoire dans mon script PHP, j'apelle bien "pg_free_result" sur le résultat, le problème est ailleur.

        J'ai l'impression que PHP ne libère pas réellement les variables liées a postgresql.

        Peut être un problème au niveau du garbage collector.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.