2010-12-08 71 views
4

Lors de la création d'un nouveau tableau (et élément) en utilisant des tableaux PHP simples, le code suivant utilise 360 ​​octets en PHP 5.3 avec et sans APC. Même l'ajout d'un élément à $ _GET n'utilise que 304 octets. Cependant, lors de la création d'un élément supplémentaire dans $ _SERVER, le même code utilise 4 896 octets! Qu'est-ce qui fait que le tableau $ _SERVER utilise tellement de mémoire supplémentaire? Qu'est-ce qui se passe dans le monde?

Répondre

2

L'explication de Mike sur la façon dont PHP alloue dynamiquement la table de hachage interne pour les tableaux est sur place. Le doublement de la taille est très performant pour allouer dynamiquement des tableaux. Cependant, les superglobales $ _SERVER, $ _REQUEST, $ _POST, $ _GET et $ _ENV ont toutes une taille fixe au démarrage du script. Ils ne sont généralement pas édités (je le décourage).

Il est très probable qu'ils sont créés avec des tables de hachage qui sont juste assez grandes pour s'adapter à leur taille actuelle. Tout ajout déclencherait alors l'algorithme d'expansion dynamique pour reconstruire et copier dans la table de hachage.

4

Je ne m'inquiéterais pas des détails de bas niveau comme ça si je développais sur PHP. Ce qui se passe probablement est que vous avez atteint une limite de capacité sur $ _SERVER, et PHP doit créer une nouvelle table de hachage qui est le double de la taille de la table de hachage actuelle. Puisqu'il s'agit de tableaux associés ordonnés, il y a un coût assez élevé pour chaque élément de la table de hachage, même les points qui ne sont pas remplis.

Si vous êtes intéressé par la mécanique de ce processus, ils sont disponibles dans zend_hash.c, ligne 418.

Pour tester cela, prendre un var_dump de votre _SERVER $ puis le mettre dans le script. Assurez-vous de ne pas tester une table de hachage fictive pour plusieurs raisons: (1) il existe différents chemins de code C pour les "tableaux dynamiques" php par rapport aux "tables de hachage" php (il les convertit pour vous), et (2) le problème peut être de copier autant de chaînes sur la nouvelle table de hachage pour éviter la sécurité des threads ou la surcharge du pointeur.

+0

5kb de surcharge dans des endroits aléatoires pour les valeurs NULL est certainement quelque chose à surveiller. Cependant, si la table de hachage est la réponse, je peux peut-être dupliquer le problème en remplissant un tableau PHP et en regardant l'utilisation de la mémoire. – Xeoncross

+0

Ouais, je voudrais d'abord vider le contenu de $ _SERVER et tester avec votre propre copie d'abord. –

+0

Ok, je viens de créer lentement un tableau et à 8, 16, 32, 64 etc .. le tableau montre des sauts de mémoire plus importants de 128, 160, 224, & 352 octets. Cependant, cela ne s'additionne pas parce que mon tableau de serveurs ne contient que 70 éléments (bien avant le prochain saut de 128 éléments) mais il saute de plus de 4kb pour seulement un autre élément 'NULL'. – Xeoncross