J'ai une chose d'objet simple capable d'avoir des enfants du même type.
Cet objet a une méthode TOHTML, qui fait quelque chose comme: p> Le problème est que lorsque l'objet est complexe, comme beaucoup d'enfants avec enfants avec enfants, etc., Skyrockets d'utilisation de la mémoire. P> si je Comment puis-je résoudre ce problème? P> =============================== ====== P> Fabriqué une classe simple similaire à mon code réel (mais plus petit): p> et tests: P > print_r code> Le tableau multidimensionnel qui nourrit cet objet I Obtenez une utilisation de la mémoire 1 Mo, mais après que je convertitais la matrice à mon objet et faire
impression $ root-> tohtml () code> il faut 10 Mo !! P>
$big = array_fill(0, 500, true);
$big[5] = array_fill(0, 200, $big);
print_r($big);
// memory_get_peak_usage() shows 0.61 MB
$root = obj::build('root', $big);
// memory_get_peak_usage() shows 18.5 MB wtf lol
print $root->toHTML();
// memory_get_peak_usage() shows 24.6 MB
4 Réponses :
Le problème est que vous tamponnez toutes les données en mémoire, que vous n'avez pas à faire, car vous venez de sortir les données, plutôt que de le traiter réellement.
plutôt que de tamponner tout la mémoire, si tout ce que vous voulez faire est de la sortie, vous devez simplement le sortir à l'endroit où vous allez: p> ou si vous souhaitez enregistrer la sortie dans un fichier p> évidemment, je ne l'ai évidemment implémenté que pour la fonction tohtml () code> mais le même principe doit être effectué pour la version code> code> fonction, qui pourrait vous conduire à sauter une fonction distincte TOHTML du tout. p> p>
Intéressant, écrire à la même variable (j'utilise globalement) semble réduire l'utilisation de la mémoire un lot b>, mais cela limite certaines possibilités, telles que les parties d'emballage de la chaîne dans les étiquettes, etc.
Pourquoi travailler avec fopen ('php: // stdout', 'w'); code> et pas seulement utiliser
echo code>? Considérant qu'il a une sortie HTML, je pense que c'est sûr de supposer qu'elle ne fonctionne pas de la ligne de commande
@Hugodelsing i) J'ai gardé le code effectuant la même chose qu'avant de manière à ce qu'il s'agisse d'une comparaison équitable II), elle permet à la fonction d'être réutilisée pour générer une version statique pour une utilisation future, de sorte que l'opération coûteuse puisse être ignorée.
@Hugodelsing utilisant un flux permet d'écrire à la mémoire, aux fichiers ou au flux de sortie. C'est beaucoup plus polyvalent et rend le test beaucoup plus facile.
Nombre total d'éléments de votre réseau est un peu de plus de 100 000.
Chaque élément de votre réseau n'est qu'un octeen (booléen), donc pour plus de 100 000 éléments qu'il prend 100000Bytes ~ 0,1 Mo P>
chacun de vos objets est ~ 100 octets il est 100 * 100000 = 100000000 octets ~ 10 Mo P>
mais vous avez ~ 18 Mo alors où est-ce que 8 de? p>
Si vous exécutez ce code p> Vous remarquerez qu'un changement est constant avec une exception pour les objets créés comme
1024th, 2048e, 4096th ... p> Je n'ai pas de lien avec un article ou une page manuelle à ce sujet, mais je suppose que PHP détient des références à chaque objet créé en matrice avec la taille initiale de 1024. Vous rendez cette matrice pleine sa taille sera doublée pour créer de la place pour de nouveaux objets. P> Si vous prenez la différence par rapport à l'exemple 2048ème objet Soustraire une taille d'objet (la valeur constante que vous avez dans d'autres lignes) et diviser En 2048, vous obtiendrez toujours 32 - Taille standard de pointeur en c. p> Donc, pour 100 000 objets ce tableau de taille de 131072.
131072 * 32 = 4194304B = 4MB P> Ce calcul est juste approximatif mais je pense que cela répond à votre question, ce qui prend tellement de mémoire. P> Pour répondre à la mémoire à basse mémoire - Évitez d'utiliser des objets Pour un grand ensemble de données. P> Les objets évidemment sont beaux et que les types de données primitifs sont plus rapides et plus petits. P> Peut-être que vous pouvez le faire fonctionner avec un seul objet contenant des données. Difficile de proposer une alternative sans plus d'informations sur ces objets et quelles méthodes / interface dont ils ont besoin. p> p>
Étant donné que vous allez sortir de la sortie du code HTML, il n'est pas nécessaire de l'enregistrer indirectement de mémoire. P> Voici une classe simple qui: p> Exemple fort> p> sortie p> comparer simple p> sortie p> classe utilisée em> p> conclusion forte> p> Comme vous pouvez le voir en boucle avec itérateur est rapide mais que les valeurs de stockage dans Itératrice ou objet peuvent ne pas être aussi efficaces. P> P>
socket code>,
flux code>,
fichier code>,
array code>,
itérateur code> etc li>
ul>
Une chose qui pourrait vous attraper, c'est que vous serez peut-être près de souffler votre pile à cause de la récursivité. Cela pourrait avoir un sens dans ce cas de créer une fonction de rendu qui traite de l'arbre dans son ensemble pour rendre au lieu de s'appuyer sur la récursivité pour faire le rendu pour vous. Pour des sujets informatifs sur cette section Voir l'optimisation de la récursion de l'appel de la queue et de l'appel de la queue.
S'en tenir à la structure actuelle de votre code et esquivez beaucoup aux problèmes de ressources que vous risquez probablement de la solution la plus simple peut être simplement de passer simplement dans la chaîne HTML comme référence comme: p> Cela vous empêchera de transporter autour d'un tas de rendements partiels en double, tandis que les appels récursifs résolvent. P> Quant à la construction réelle de l'arborescence, je pense que beaucoup de l'utilisation de la mémoire est Juste le prix de la lecture avec des données qui grandes, vos options sont soit une restitution au lieu de construire un modèle hiérarchique juste pour rendre (simplement rendez-vous au lieu de construire un arbre) ou d'employer une sorte de stratégie de mise en cache pour les copies de cache de L'arborescence d'objet ou des copies du HTML rendu en fonction de la manière dont les données sont utilisées sur votre site. Si vous avez le contrôle des données entrantes, une invalidation des touches de cache pertinentes peut être ajoutée à ce flux de travail pour empêcher le cache de faire obstacle. p> p>
Est-ce 10 Mo avant ou après avoir appelé
tohtml () code>?
Ce 10M pourrait être un nu minimum que PHP prend pour certaines opérations - comme cela se passe, ce n'est pas une grande mémoire pour les processus Web PHP. Je suppose que vous ne trouverez pas ce sauteur X10 linéaire, donc si vous double du nombre d'enfants, il ne saute pas à 20 m. Essayez-le, cependant! Avez-vous particulièrement besoin de le limiter à un très faible niveau d'utilisation? Sinon, je serais enclin à ne pas m'inquiéter à ce sujet.
Je ne pense pas que cela soit vrai, car si je double la taille de la matrice, l'utilisation de la mémoire double aussi
(N'oubliez pas d'aborder les gens par leur poignée ici, par exemple @halfer, sinon ils ne peuvent pas voir votre réponse. Je n'ai pas besoin de le faire pour vous, car c'est votre message).
Je sais que cela ne répond pas à la question exacte, mais la chaîne HTML totale est-elle nécessaire à la fois? Ne pouviez-vous pas diffuser dans un fichier (ou une prise, si c'est le cas) à la place?
Avez-vous essayé simplement d'utiliser Memcache ....?