Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
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 29/04/2008, 12h20   #1
Modérateur
 
Avatar de Er3van
 
Homme Clément
Architecte Logiciel
Inscription : avril 2008
Messages : 1 370
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 370
Points : 2 093
Points : 2 093
Par défaut [Système] Espace maximum allouable

Bonjour,

Toujours dans la continuité de ce que je fais depuis qq temps pour ceux qui m'ont déjà aidé ( notamment jml94 ), je stocke des arborescence de fichiers ( de serveurs ) sous forme de tableau.

Pour un gain de temps, pour éviter d'avoir à relancer l'algo qui construit l'arborescence d'un serveur ( qui dure 2 bonnes minutes ), une fois que celle-ci est créée, elle est stockée dans une variable de session. Seulement voilà, l'espace alloué dépasse les limites authorisées, du moins, c'est ce que j'en ai déduit à la lecture de ce message :

Citation:
Envoyé par L'indien
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 1572930 bytes) in Unknown on line 0
Et mon code associé :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
	if ( !isset($_SESSION["{$_SESSION['nomServeur']}"]) ) { // Si on n'a pas deja charger ce depot
		// Appel à la fonction dessin_arborescence
		$arbo = dessin_arborescence($_SESSION['urlSource']) ;
	}
	else { // Si on a deja charge ce depot, on a juste a le recupperer
		$arbo = $_SESSION["{$_SESSION['nomServeur']}"] ;
		$monTableau = $arbo[0] ;
		$tailleTableau = $arbo[1] ;
		$nomArbo = $_SESSION['urlSource'] ;
 
		// On apppelera la vue d'affichage de l'arborescence
		$_SESSION['vue'] = "Vue_Arbo.php" ;
	}
Je voulais donc savoir, d'une part si j'avais bien interprêté le message, et d'autre part quelle est la taille maximum allouable dans les variables de sessions php.

Enfin, si vous avez des suggestions pour passer outre cette limite, je suis tout ouïe !
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 13h59   #2
Membre éprouvé
 
Homme
Inscription : août 2006
Messages : 313
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2006
Messages : 313
Points : 497
Points : 497
Pour combattre un dépassement mémoire sur une variable session. la technique la plus bourrin est d'augementer le memory_limit (actuellement a 16M chez toi) dans la configuration php.

Pour ton script, pourquoi n'utilises tu pas un fichier de cache ?

N'empeche pour avoir un tableau de 16 mega, tu dois en avoir beaucoup des fichiers dans ton arbo.

Aille, j'ai compris. Ton problème ne vient pas de la taille de ton tableau qui fait : 1 M 5 mais surtout du fait que tu dois avoir plusieur dizaine d'utilisateurs

Des fichiers de cache résoudra tous tes problèmes je pense avec une reference dans la session.
Phelim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 14h07   #3
Modérateur
 
Avatar de Er3van
 
Homme Clément
Architecte Logiciel
Inscription : avril 2008
Messages : 1 370
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 370
Points : 2 093
Points : 2 093
Citation:
Aille, j'ai compris. Ton problème ne vient pas de la taille de ton tableau qui fait : 1 M 5 mais surtout du fait que tu dois avoir plusieur dizaine d'utilisateurs
Heu, mon site n'est pas en ligne, intranet uniquement, et il n'y a qu'un seul et unique utilisateur pour le moment : moi ^^

Citation:
N'empeche pour avoir un tableau de 16 mega, tu dois en avoir beaucoup des fichiers dans ton arbo.
Plus ou moins 5000 fichiers par serveur

Citation:
Pour ton script, pourquoi n'utilises tu pas un fichier de cache ?
Heu, kézako ? ^^'


En tout cas merci de ton aide, j'vais me renseigner au sujet des fichiers de cache.
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 14h22   #4
Membre éprouvé
 
Homme
Inscription : août 2006
Messages : 313
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2006
Messages : 313
Points : 497
Points : 497
Il s'agit simplement de stocker ton tableau dans un fichier (tu peux le serializer).

Cette action soulage la mémoire vive. C'est valable si tu n'y accedes pas plusieurs fois par script.
Si tu y accedes qu'une fois tous les 10 scripts, cette solution est extremement rentable. Meme une fois, ça evite l'usage des sessions.

Les sessions doivent eviter d'etre utilisé pour des gros caches car PHP les transporte en permanence en memoire (en faite il les charge depuis un fichier au demarrage du script et il les reenregistre à nouveau dans un fichier a la fin)

Dans ton traitement de parcours du serveur, es tu sur de parfaitement liberer la memoire au fur et a mesure, car tu as plus de 14M 5 dans la memoire de php, c'est enorme.

C'est vraiment grave car imagine ce qu'il va se passer quand tu passeras en production avec 5 ou 6 utilisateurs en //

Utilise tu des boucles foreach ?
Phelim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 14h34   #5
Modérateur
 
Avatar de Er3van
 
Homme Clément
Architecte Logiciel
Inscription : avril 2008
Messages : 1 370
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 370
Points : 2 093
Points : 2 093
Ok, j'viens de lire un exemple et ça m'a l'air assez simple.

En fait, j'ai un script qui créer un tableau en parcourant l'arborescence fichier d'un serveur ( via des commandes exec() ).
Après, j'ai deux pages succeptibles d'y accéder, mais c'est surtout parceque l'opération est longue ( la faute aux 5000 fichiers.... ) qu'il est pratique de sauvegarder le résultat.

Dans la ligne d'erreur que j'ai donnée, c'était après avoir chargé plusieurs arborescence, 2 ou 3, dans le tableau $_SESSION, ce n'est pas le fruit d'une seule arborescence.

Sinon, oui j'utilise un foreach, mais pas à la lecture du tableau, uniquement quand je le rempli ( et pas vraiment le choix ).

Code :
1
2
3
exec('ls XXXXX', $liste, $retour) ;
if ( $retour == 0 )
    foreach ( $liste as $element )
Vu que je ne connais pas la taille de $liste, foreach est la solution la mieux adaptée à mon avis.

Merci encore
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 14h43   #6
Membre éprouvé
 
Homme
Inscription : août 2006
Messages : 313
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2006
Messages : 313
Points : 497
Points : 497
Tout a fait foreach est la boucle la plus adapté mais c'est une boucle traitre.
Elle travaille sur la copie de ton tableau donc si il est gros, tu charges beaucoup en memoire.

Pour optimiser emploie cette syntaxe :

Citation:
foreach ($arr as &$value) {
$value = $value * 2;
}
Ainsi, tu travailles sur la reference de ton tableau et evite un nouveau chargement en memoire.
Evite a tout prix, si tu as plusieurs tableaux, de tous les charger en memoire. Fichier cache obligatoire par fichier et tu charges le fichier quand tu as besoin.

Ton script est un PHP cli (en ligne de commande ?)

*Edit* Aille la commande linux. Je suis pas sur que ça soit super optimisé mais surtout ça rend ton script non portable. Pourquoi n'emploie tu pas scandir() ?

Il doit meme exister des class PHP optimisé pour ce genre de traitement
Phelim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 14h55   #7
Modérateur
 
Avatar de Er3van
 
Homme Clément
Architecte Logiciel
Inscription : avril 2008
Messages : 1 370
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 370
Points : 2 093
Points : 2 093
Oui, la plupart de mes actions sont faites en lignes de commande.
Pour ce qui est la référence, avec PHP on ne travaille pas toujours sur des références ?


Pour le script, le plus simple c'est encore de te le montrer :

Prérequis : Je travaille sur Subversion, c'est un logiciel de versionning qui gère les fichiers, normalement c'est fait pour un developpement multi développeurs, mais dans ce cas ça sert à gérer les modifs apportées à des fichiers de config sur les serveurs. Subversion permet de fournir des infos sur les fichiers/dossiers via certaines commandes, donc svn info que j'utilise.
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
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
80
81
82
83
84
85
86
87
88
89
/**
	* @description	Initialise les variables et appelle la fonction arborescence() 
	*			Renvoie un tableau a deux dimensions contenant le tableau 
	*			OU false si le repertoire racine passe en parametre n'existe pas
	*			representant l'arborescence et le nombre d'elements du tableau
	* @author		[DSIT-XIS/SO]
	* @date		22/04/2008
	* @param		$urlPere				L'url de la racine de l'arborescence
	*/
	function dessin_arborescence ($urlPere) {
		$temp = array(array()) ;
		exec('ls '.$urlPere, $puit, $test) ;
		if ( $test != 0 )
			return false ;
		$temp = arborescence ($urlPere) ;	
		return $temp ;	
	}
 
	/**
	* @description	Parcours une arborescence recursivement. 
	*			Construit un tableau a trois dimensions de type [i][j][donnees]  au fur et a mesure
	* @author		[DSIT-XIS/SO]
	* @date		22/04/2008
	* @param		$urlPere				L'url de la racine de l'arborescence
	*/	
	function arborescence ($urlPere) {
		// --------- FONCTION RECURSIVE -------
		// Parcours une arborescence recursivement et construit un tableau a trois dimensions de type [i][j][donnees]  au fur et a mesure
		static $i = -1 ;
		static $j = 0 ;
		static $monTableau = array(array(array())) ;
		static $compteur = 0 ;
 
		// On regarde le contenu du dossier
		exec('ls '.$urlPere,$liste) ;
 
		// Pour chaque element contenu dans le dossier racine
		foreach ( $liste as $element ) {
			$i++ ;
			$urlElement = $urlPere.'/'.$element ;
 
			// On teste s'il s'agit d'un dossier ou d'un fichier
			exec('[ -d '.$urlElement.' ]', $puit, $testDossier);
 
			unset($date);
			unset($rev);
 
			// On insere l'element au tableau
			$monTableau[$i][$j]['nom'] = $element ;
			$monTableau[$i][$j]['url'] = $urlElement ;
			exec('svn info '.$urlElement. ' | grep "Last Changed Date" | cut -d: -f2 | cut -d" " -f2', $date) ;
			exec('svn info '.$urlElement. ' | grep "Last Changed Rev" | cut -d: -f2 | cut -d" " -f2', $rev) ;
			$monTableau[$i][$j]['rev'] = $rev[0] ;
			$monTableau[$i][$j]['date'] = $date[0] ;
			$monTableau[$i][$j]['src'] = substr($urlElement, 29 ).'/Reference'.substr($urlElement, 33 ) ;
			//exec('diff '.$urlElement.' '.$src, $tabTest, $modif) ;
 
			// On teste s'il s'agit d'un dossier ou d'un fichier
			exec('[ -d '.$urlElement.' ]',$tabTest, $testDossier);	
			if ( $testDossier == 0 ) {
				$monTableau[$i][$j]['type'] = 'dn' ;	
 
				// Appel recursif a partir du sous-dossier
				$j++ ;
				$compteur++ ;
				arborescence ($urlElement) ;
				$compteur-- ;
				// On remonte dans l'arborescence
 
 
			}
				// Si l'element est un fichier :	
			else {
				exec('[ -f '.$urlElement.' ]', $puit, $testFichier);
				if ( $testFichier == 0 ) {
					$monTableau[$i][$j]['type'] = 'fn' ;				}
			}
		}
		$i++ ;
		$monTableau[$i][$j]['nom'] = ' ' ;
		$monTableau[$i][$j]['url'] = ' ' ;
		$monTableau[$i][$j]['rev'] = ' ' ;
		$monTableau[$i][$j]['date'] = ' ' ;
		$monTableau[$i][$j]['type'] = ' ' ;
		$j-- ;
		$temp[0] = $monTableau ;
		$temp[1] = $i ;
		return $temp ;
		}
Normalement je gère aussi les différences entre plusieurs fichiers, mais je l'ai enlevée pour ne pas surcharger inutilement.
Au final, je me retrouve avec plusieurs tableaux $liste en mémoire au même moment, mais de petite taille, généralement les tableau en question ne dépassent pas les 10 lignes. Le seul gros tableau c'est $monTableau.
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 15h22   #8
Membre éprouvé
 
Homme
Inscription : août 2006
Messages : 313
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2006
Messages : 313
Points : 497
Points : 497
Ok, je vois svn est assez contraignant et empeche d'utiliser les instructions php.

5000 fichiers = 5000 lignes avec 300 octet (300 caractere, je pense viser large)
150 000 octet : 150 koctet
toi : tried to allocate 1572930 bytes 1M5 10 X plus

Cote optimisation, y'a du travail, mais je vois pas ou ça peut bouffer autant de memoire que ça.
Phelim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 15h35   #9
Modérateur
 
Avatar de Er3van
 
Homme Clément
Architecte Logiciel
Inscription : avril 2008
Messages : 1 370
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 370
Points : 2 093
Points : 2 093
J'viens d'essayer de reprovoquer l'erreur et ça ne le fait encore :
Citation:
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 2359375 bytes) in Unknown on line 0
En allouant cette fois 3 tableau, j'en déduit qu'un tableau fait plus ou moins 750Ko, ce qui n'est pas non plus énorme.
Je stocke un nom de 10 car, une url absolu de plus ou moins 40/50 voire 60 car, une seconde url absolue de la même taille, une date de 12 car, un numero de 8 octets, et un type de 2 car. Sachant que tout ça est contenu dans un tableau à 3 dimensions, ça fait pas loin du compte.
8+8+(10+2*50+12+8+2 = 132) * 5000 = 740Ko.

Sinon, ton
Code :
1
2
3
foreach ($arr as &$value) {
$value = $value * 2;
}
ne fonctionne pas...

Pour la mise en cache j'ai un pb de droit d'accès, j'espère que ça sera pas trop problématique. :S
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 16h43   #10
Membre éprouvé
 
Homme
Inscription : août 2006
Messages : 313
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2006
Messages : 313
Points : 497
Points : 497
Bizzare, j'avais pourtant verifier dans la doc php pour le foreach.

Ben le problème c'est surtout qui utilise les autres 13 M de memoire ...
La un seul de tes tableaux fait 2M 353 (enfin si j'ai bien compris ton code)

La seule solution viable reste de mettre en cache à tout prix. Ben pour mettre en cache, il faut au moins pouvoir ecrire un fichier et le lire quelque part. Ne pas oublier que le fichier doit correspondre à un utilisateur unique (donc composé le nom avec le numero de session)
Phelim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 16h55   #11
Modérateur
 
Avatar de Er3van
 
Homme Clément
Architecte Logiciel
Inscription : avril 2008
Messages : 1 370
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 370
Points : 2 093
Points : 2 093
Non justement, le fichier dans le cache ne doit pas dépendre de l'utilisateur, sinon ça ne sert pas à grand chose. Un fichier par tableau/serveur/arborescence.
La gestion des droits est suffisante pour avoir une confiance totale en l'utilisateur ( qui de toute façon ne peut rien faire de mal sur un dépôt SVN... ).

Pour ce qui est du "trou" de mémoire, je ne suis pas sûr que ça en soit vraiment un, il faudrait que je vois ça de plus près mais ce n'est pas ma plus grande préoccupation du moment ^^

En tout cas merci pour ton aide
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 17h00   #12
Membre éprouvé
 
Homme
Inscription : août 2006
Messages : 313
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 27
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Secteur : High Tech - Électronique et micro-électronique

Informations forums :
Inscription : août 2006
Messages : 313
Points : 497
Points : 497
Lol alors qu'est ce que ça faisait dans les variables de session

Les variables de session sont propres à chaque utilisateur. Les utiliser pour des données communes, c'est du suicide car il faut les charger pour chacun.
Phelim est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 17h03   #13
Modérateur
 
Avatar de Er3van
 
Homme Clément
Architecte Logiciel
Inscription : avril 2008
Messages : 1 370
Détails du profil
Informations personnelles :
Nom : Homme Clément
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Architecte Logiciel
Secteur : Industrie

Informations forums :
Inscription : avril 2008
Messages : 1 370
Points : 2 093
Points : 2 093
J'avais hésité à caler ça dans le tableau global, mais session était aussi une solution, puisque d'une manière générale il n'y aura jamais deux utilisateurs connectés en même temps ( ou rarement, et plus de deux quasiment jamais ).

'Fin bref, je verrais ça à tête reposée
__________________
One minute was enough, Tyler said, a person had to work hard for it, but a minute of perfection was worth the effort. A moment was the most you could ever expect from perfection.

-- Chuck Palahniuk, Fight Club, Chapter 3 --
Er3van 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 20h14.


 
 
 
 
Partenaires

Hébergement Web