Discussion:
Est-ce que l'on peut manquer d'espace en PHP ?
(trop ancien pour répondre)
Denis Beauregard
2011-10-24 18:25:25 UTC
Permalink
Bonjour,

Je me pose la question académique suivante : j'ai un logiciel qui
lit des données dans une base de données, puis enregistre chaque
bloc et passe au suivant, ceci sans détruire quoi que ce soit.
Est-ce qu'il arrive un moment où le logiciel n'aura plus d'espace
mémoire pour travailler ? Je précise que j'ai le time out par
défaut de 30 secondes, une mémoire de 4 Go, un WAMP, et que j'ai
déjà des scripts qui plantent après 30 secondes et qui lisent des
données sans rien détruire, mais toujours dans des chaînes
réutilisées. Mes scripts avancent dans la base de données et après
30 secondes, recommencent à la fiche où l'itération précédente a
échoué.

En d'autres mots, j'ai une classe Famille, j'y insère des données
de longueur variable (parents, grands-parents, enfants et conjoints)
et je ne nettoie jamais rien. Je construis une famille, puis une
autre, etc. J'ai un manuel du PHP et je ne vois pas de "destructeur"
dans l'index.


Denis
Mickaël Wolff
2011-10-25 00:23:41 UTC
Permalink
Post by Denis Beauregard
Bonjour,
Je me pose la question académique suivante : j'ai un logiciel qui
lit des données dans une base de données, puis enregistre chaque
bloc et passe au suivant, ceci sans détruire quoi que ce soit.
Est-ce qu'il arrive un moment où le logiciel n'aura plus d'espace
mémoire pour travailler ?
Forcément, nos ordinateurs sont limités :)
Post by Denis Beauregard
une mémoire de 4 Go, un WAMP
32bit ou 64bit ? L'espace mémoire que PHP peut allouer à ces petits
dépend de l'OS, de la taille du mot machine et du nombre de pages
mémoire que le matériel et son usage le permettent.
Post by Denis Beauregard
, et que j'ai
déjà des scripts qui plantent après 30 secondes et qui lisent des
données sans rien détruire, mais toujours dans des chaînes
réutilisées. Mes scripts avancent dans la base de données et après
30 secondes, recommencent à la fiche où l'itération précédente a
échoué.
Sont-ce des outils en CLI ou servies par le Web ?
Post by Denis Beauregard
En d'autres mots, j'ai une classe Famille, j'y insère des données
de longueur variable (parents, grands-parents, enfants et conjoints)
et je ne nettoie jamais rien. Je construis une famille, puis une
autre, etc. J'ai un manuel du PHP et je ne vois pas de "destructeur"
dans l'index.
C'est un peu trop vague ;)
Denis Beauregard
2011-10-25 03:10:15 UTC
Permalink
Le Tue, 25 Oct 2011 02:23:41 +0200, Mickaël Wolff
Post by Mickaël Wolff
Post by Denis Beauregard
Bonjour,
Je me pose la question académique suivante : j'ai un logiciel qui
lit des données dans une base de données, puis enregistre chaque
bloc et passe au suivant, ceci sans détruire quoi que ce soit.
Est-ce qu'il arrive un moment où le logiciel n'aura plus d'espace
mémoire pour travailler ?
Forcément, nos ordinateurs sont limités :)
Mais jusqu'à quel point ? En ce moment, je n'ai pas rencontré d'erreur
de manque de mémoire et j'alloue constamment des chaînes de caractères
sans rien effacer jusqu'au plantage après 30 secondes.
Post by Mickaël Wolff
Post by Denis Beauregard
une mémoire de 4 Go, un WAMP
32bit ou 64bit ? L'espace mémoire que PHP peut allouer à ces petits
dépend de l'OS, de la taille du mot machine et du nombre de pages
mémoire que le matériel et son usage le permettent.
64 bits, Windows 7 familial SP1
mysqld prend 180 Mo de mémoire et c'est le plus gros processus relié
à PHP sur mon ordi (valeur lue pendant l'exécution d'un script).
Post by Mickaël Wolff
Post by Denis Beauregard
, et que j'ai
déjà des scripts qui plantent après 30 secondes et qui lisent des
données sans rien détruire, mais toujours dans des chaînes
réutilisées. Mes scripts avancent dans la base de données et après
30 secondes, recommencent à la fiche où l'itération précédente a
échoué.
Sont-ce des outils en CLI ou servies par le Web ?
Je suppose que CLI signifie en local. Dans ce projet, j'utilise
EasyPHP comme Wamp sur un PC personnel. C'est donc un serveur en
local. J'ai environ 350 000 lignes à traiter (validation puis
affichage de données).
Post by Mickaël Wolff
Post by Denis Beauregard
En d'autres mots, j'ai une classe Famille, j'y insère des données
de longueur variable (parents, grands-parents, enfants et conjoints)
et je ne nettoie jamais rien. Je construis une famille, puis une
autre, etc. J'ai un manuel du PHP et je ne vois pas de "destructeur"
dans l'index.
C'est un peu trop vague ;)
J'ai fini par trouver les constructeurs et destructeurs sur php.net.
Il semble que cela soit disponible avec la version 5 alors que mon
bouquin date de 2003. Mais je ne prévois pas utiliser de destructeurs.

Mon logiciel se relance tout seul (via une META refresh) et je ne
verrais pas de message s'il y a un manque de mémoire.


Denis
Vincent Verdon
2011-10-26 21:25:10 UTC
Permalink
Bonsoir,
Post by Denis Beauregard
Post by Mickaël Wolff
Post by Denis Beauregard
une mémoire de 4 Go, un WAMP
32bit ou 64bit ? L'espace mémoire que PHP peut allouer à ces petits
dépend de l'OS, de la taille du mot machine et du nombre de pages
mémoire que le matériel et son usage le permettent.
64 bits, Windows 7 familial SP1
mysqld prend 180 Mo de mémoire et c'est le plus gros processus relié
à PHP sur mon ordi (valeur lue pendant l'exécution d'un script).
Cela me semble énorme. Chez-moi, mysqld consomme quelques % de la
mémoire. Maintenant, c'est à vide...
Post by Denis Beauregard
Post by Mickaël Wolff
Sont-ce des outils en CLI ou servies par le Web ?
Je suppose que CLI signifie en local. Dans ce projet, j'utilise
EasyPHP comme Wamp sur un PC personnel. C'est donc un serveur en
local. J'ai environ 350 000 lignes à traiter (validation puis
affichage de données).
Non. CLI signifie Command Line Interface, donc interface en ligne de
commande. D'après ce que tu indique, ce n'est pas le cas, PHP est
utilisé avec Apache.
Post by Denis Beauregard
Post by Mickaël Wolff
Post by Denis Beauregard
En d'autres mots, j'ai une classe Famille, j'y insère des données
de longueur variable (parents, grands-parents, enfants et conjoints)
et je ne nettoie jamais rien. Je construis une famille, puis une
autre, etc. J'ai un manuel du PHP et je ne vois pas de "destructeur"
dans l'index.
__destruct() , non ?

Amicalement, Vincent Verdon
franssoa
2011-10-27 10:54:36 UTC
Permalink
Post by Vincent Verdon
Cela me semble énorme. Chez-moi, mysqld consomme quelques % de la
mémoire. Maintenant, c'est à vide...
Ici aussi, 1.5% de la mémoire en lui faisant faire des manip sur notre
intranet.
Vincent Verdon
2011-10-27 12:40:52 UTC
Permalink
Je ne suis pas sûr d'avoir toute la question mais dans le php.ini, il y
à une directive "memory_limit" qui fixe la taille
limite que le processus peut atteindre en terme de mémoire.

La méthode __ destruct ici ne me parait pas pertinente ( surtout
utiliser pour libérer des ressources) ,
en fait, à la fin de chaque processus, un garbage_collector (php5.3+)
nettoie la mémoire utilisée.

plus d'info sur http://fr.php.net/manual/en/features.gc.php

si le script spécifique nécessite réellement plus de mémoire , utiliser
ini_set(‘memory_limit’,’64M’);

en sachant qu'il est fort probable qu'une solution moins consommatrice
doit exister et qu'il est souhaitable d'optimiser le script avant de
modifier la configuration de php, afin de s'assurer que, si le script
est distribué, il fonctionnera sur toutes les configurations.

Cordialement,

Aurélien.
Denis Beauregard
2011-10-27 13:12:48 UTC
Permalink
Le Thu, 27 Oct 2011 14:40:52 +0200, Vincent Verdon
Post by Vincent Verdon
Je ne suis pas sûr d'avoir toute la question mais dans le php.ini, il y
à une directive "memory_limit" qui fixe la taille
limite que le processus peut atteindre en terme de mémoire.
La méthode __ destruct ici ne me parait pas pertinente ( surtout
utiliser pour libérer des ressources) ,
En fait, je ne manipule que des chaînes de caractères. Au début, je
crée un objet Famille qui contient environ 36 objets Personne (les
parents, grands-parents et 30 enfants possible, le max effectif étant
de 21), et ces objets contiennent eux aussi des objets Actes. Une fois
le processus lancé, rien d'autre n'est ajouté sinon des chaînes. Je
lis une fiche, je l'insère dans l'objet Famille (toujours des
$this->prenom = $li['prenom'] par exemple), je fais des tests et
je recommence avec la fiche suivante.
Post by Vincent Verdon
en fait, à la fin de chaque processus, un garbage_collector (php5.3+)
nettoie la mémoire utilisée.
plus d'info sur http://fr.php.net/manual/en/features.gc.php
si le script spécifique nécessite réellement plus de mémoire , utiliser
ini_set(‘memory_limit’,’64M’);
Il semble bien que je dépasse les 180 Mo pour mySQL, donc la limite
par défaut est sans doute déjà suffisante.
Post by Vincent Verdon
en sachant qu'il est fort probable qu'une solution moins consommatrice
doit exister et qu'il est souhaitable d'optimiser le script avant de
modifier la configuration de php, afin de s'assurer que, si le script
est distribué, il fonctionnera sur toutes les configurations.
Ce script ne sert que sur mon ordi, en local. J'ai en gros 4 scripts
à faire. Le premier fait la validation initiale des données, le second
relit toutes les données sur mon ordi pour produire des pages web
statiques (pour faire un CD-ROM statique pour diffusion) et un 3e pour
que je vois les données chez moi pour mes travaux. Un dernier script
est destiné à Internet et affichera une seule fiche à la fois, donc,
comme le 3e, il n'aura pas de grands besoins de mémoire.

Ma crainte serait que le second script, que je n'ai pas encore fait,
émette une fiche incomplète par manque de mémoire, vu que je ne
pourrai pas savoir si la dernière fiche d'une itération est complète.
Par contre, je peux prendre pour acquis que s'il y a un manque de
mémoire, le processus arrête (et est relancé par la META refresh)
et donc je peux tout simplement reculer de 1 fiche quand je reprends
la production des fiches pur diffusion.

J'ai déjà pris pour acquis que même en augmentant de beaucoup la
limite en temps, je ne serai jamais assuré que je ne l'ai pas dépassée
vu que ma base de données va augmenter avec le temps, donc je conserve
le 30 secondes par défaut. Je précise que je fais quelques milliers
d'itérations par 30 secondes (autour de 10 000).

Pour ce qui est de l'espace disponible, je suppose que si je n'ai plus
de mémoire, il y aura plantage. Mais est-ce possible que cela ne se
produise pas (donc que le programme continue mais que certaines
chaînes plus longues ne soient pas valides) ou bien est-ce que la
mémoire est vidée automatiquement quand il n'y a plus d'espace ? J'ai
cette configuration :

EasyPHP 5.3.8.1

PHP 5.3.8 VC9
Apache 2.2.21 VC9
MySQL 5.5.16
PhpMyAdmin 3.4.5
Xdebug 2.1.2


Denis
Mickaël Wolff
2011-10-31 17:12:04 UTC
Permalink
Post by Vincent Verdon
Je ne suis pas sûr d'avoir toute la question mais dans le php.ini, il y
à une directive "memory_limit" qui fixe la taille
limite que le processus peut atteindre en terme de mémoire.
Ce n'était pas ça question, Denis s'interroge sur les limites en
resources mémoire qu'une application PHP peut utiliser.
Post by Vincent Verdon
La méthode __ destruct ici ne me parait pas pertinente ( surtout
utiliser pour libérer des ressources) ,
Absolument pas. La fonction membre __destruct est appelée lors de la
destruction de la dernière référence vers un objet de la classe
définissant le destructeur.
Post by Vincent Verdon
en fait, à la fin de chaque processus, un garbage_collector (php5.3+)
nettoie la mémoire utilisée.
Non, dans chaque contexte d'exécution de PHP, il peut y en avoir
plusieurs par processus d'exécution. À noter que les GC existent depuis
au moins la version 4 et l'introduction de la sémantique orienté objet.
Post by Vincent Verdon
en sachant qu'il est fort probable qu'une solution moins consommatrice
doit exister et qu'il est souhaitable d'optimiser le script avant de
modifier la configuration de php, afin de s'assurer que, si le script
est distribué, il fonctionnera sur toutes les configurations.
Ben non, pas forcément. Parfois un script manipule beaucoup de
mémoire sans qu'on ne puisse faire autrement. Cependant, je suis
d'accord sur le fait qu'il faille profiler pour voir si on ne peut pas
améliorer.
Mickaël Wolff
2011-10-31 17:52:16 UTC
Permalink
Post by Denis Beauregard
Mais jusqu'à quel point ? En ce moment, je n'ai pas rencontré d'erreur
de manque de mémoire et j'alloue constamment des chaînes de caractères
sans rien effacer jusqu'au plantage après 30 secondes.
Mais le plantage au bout de 30s est dû au temps maximal d'exécution
configuré dans PHP ou du dépassement de la capacité mémoire configurée
dans PHP ?

La limite dépend de nombreux paramètres :
- la limite matérielle (mémoire vive + mémoire d'échange)
- la limite d'adressage de la mémoire (2³² ou 2⁶⁴)
- l'architecture mémoire du processus, liée aux OS, au compilateur,
la fragmentation mémoire, etc.

Donc on peut donner une approximation de la mémoire disponible, mais
bien malin celui qui affirmera une limite absolue. Ah, et les autres
processus consomment aussi de la mémoire ;)
Post by Denis Beauregard
Mon logiciel se relance tout seul (via une META refresh) et je ne
verrais pas de message s'il y a un manque de mémoire.
Ben si ça te permet de faire le travail, ça ira. Si vraiment ça te
pose problème, il faut profiler. xdebug permet de profiler la
consommation mémoire et l'exécution.
Denis Beauregard
2011-10-31 20:39:41 UTC
Permalink
Le Mon, 31 Oct 2011 18:52:16 +0100, Mickaël Wolff
Post by Mickaël Wolff
Post by Denis Beauregard
Mais jusqu'à quel point ? En ce moment, je n'ai pas rencontré d'erreur
de manque de mémoire et j'alloue constamment des chaînes de caractères
sans rien effacer jusqu'au plantage après 30 secondes.
Mais le plantage au bout de 30s est dû au temps maximal d'exécution
configuré dans PHP ou du dépassement de la capacité mémoire configurée
dans PHP ?
C'est le temps maximal permis. J'ai monté à 3 minutes et cela plantait
à 3 minutes.

Pourquoi ne pas monter à 5 ou 10 minutes ? Pour différentes raisons.
Par exemple, à force d'ajouter des données ou de rendre ma validation
plus complète, je risque de dépasser le temps limite sans m'en
apercevoir. D'ailleurs, en cours de développement, j'ai des périodes
où je baisse de 10 000 à 100 itérations par 30 secondes (quand
j'utilise les tables non optimisées).
Post by Mickaël Wolff
- la limite matérielle (mémoire vive + mémoire d'échange)
- la limite d'adressage de la mémoire (2³² ou 2??)
- l'architecture mémoire du processus, liée aux OS, au compilateur,
la fragmentation mémoire, etc.
En fait, ce que je veux savoir, c'est si une telle limite existe. Par
exemple, si je ne fais qu'ajouter des données avec des strings, et que
PHP libère de la mémoire automatiquement (j'ai la dernière version de
EasyPHP, donc je pense que cela est implanté comme suggéré ailleurs
dans le fil), alors je ne devrais pas avoir de problème.
Post by Mickaël Wolff
Donc on peut donner une approximation de la mémoire disponible, mais
bien malin celui qui affirmera une limite absolue. Ah, et les autres
processus consomment aussi de la mémoire ;)
Post by Denis Beauregard
Mon logiciel se relance tout seul (via une META refresh) et je ne
verrais pas de message s'il y a un manque de mémoire.
Ben si ça te permet de faire le travail, ça ira. Si vraiment ça te
pose problème, il faut profiler. xdebug permet de profiler la
consommation mémoire et l'exécution.
Disons que c'est un travail personnel qui ne sera pas placé en soi sur
un serveur public. J'ai plusieurs scripts à préparer. La validation et
la génération des fiches se font en local. Donc, si cela ne plante
pas et qu'un débordement de mémoire est impossible à cause du
"garbage collection", alors, je n'ai pas à en tenir compte. Il y a 2
versions qui seront publiques. La 1re génère une fiche à la fois (et
non autour de 10 000 comme dans ma validation). La 2e est statique,
donc les pages ne sont générées qu'une fois, sur mon ordi.


Merci à tous pour les suggestions, idées et commentaires


Denis

Continuer la lecture sur narkive:
Loading...